Comments (7)
I've been thinking about this, and as much as I dislike some of the patterns this is used for, Avalonia 11.0 supports it and WPF supports it so Avalonia 11.1 should also support it.
from avalonia.
As @stevemonaco said, this is a bit of an edge case as you're raising PropertyChanged
on a property which hasn't changed and then relying on a stateful IValueConverter
to mutate the state differently each time. The issue is that we now check for a changed bound value earlier than before and so the converter isn't being called.
I cross-checked with WPF and it also does call the converter even if the value hasn't changed so I'm in two minds about whether we should support this use-case. On one hand we try to match WPF's behavior where it makes sense, but on the other hand it feels like this is an anti-pattern in that it's generally bad practise to rely on side-effects in bindings. It also feels like a misuse of PropertyChanged
in that if that event is raised on a property that hasn't changed, a listener should be free to ignore the event.
from avalonia.
ObservableCollection.Count can be binded to as it raises PropertyChanged for Count. Granted, that's a lot of notifications and converter calls since ObservableCollection doesn't well-support range operations.
lol, I've done it using the collection itself for so many years I never thought to check that. I never knew INotifyPropertyChanged fired for Count. Always learning, thanks!
I think stateful converters are bad practice, but I also think the ViewModel or some component in-between should be responsible for restricting notifications, if necessary.
I would say an IsNullOrEmptyConverter
isn't stateful. It's a transform of the raw information and adds nothing to it or maintains any state itself. Transforming information is exactly what converters are for. Simply speaking we want to minimize duplicate information (properties) in the view model. I'm sure there is some information theory rationale here.
Anyway, I still think we shouldn't try to outsmart application developers. Just as in WPF, if the view model wants an update it should get an update. I'm sure I can find other cases where it's needed if I looked a while.
from avalonia.
You should consider writing an IMultiValueConverter
and move the _toggle
state into the ViewModel. IMO, converters are best left as pure functions without local state.
I can confirm the regression from 11.0.11 with the repro though (rc1 and nightly), so it should be fixed.
Also, I see a use of BindingNotification
which might not work until RC2 or stable.
from avalonia.
I've run across a related issue to this that I never filed an issue for. The situation is this:
- Have a custom IsNullOrEmptyConverter bound to an ObservableCollection property. That converter is used to show "list empty, please add an item" type messages. So
ListBlock.IsVisible="{Binding ListProperty, Converter={StaticResource IsNullOrEmptyConverter}}"
in pseudocode. - In the view model, manually force the converter to update visibility by calling OnPropertyChanged("ListProperty") which should force re-calculation of the converter and hide the message. In Avalonia it does not.
This is a pattern I've used since WPF as it saves one additional property on the view model that adds no new information. For now I've had to work-around this with a "IsListEmpty" property.
I really wish the binding systems were smart enough to raise property change notification on the ListProperty when it's a collection that has INotifyCollectionChanged but we aren't there yet. So I've been using this method.
Overall though, I think there always needs to be a way for apps to force re-evaluation of bindings. That's needed in edge cases we've discussed separately anyway.
from avalonia.
As @stevemonaco said, this is a bit of an edge case as you're raising
PropertyChanged
on a property which hasn't changed and then relying on a statefulIValueConverter
to mutate the state differently each time. The issue is that we now check for a changed bound value earlier than before and so the converter isn't being called.I cross-checked with WPF and it also does call the converter even if the value hasn't changed so I'm in two minds about whether we should support this use-case. On one hand we try to match WPF's behavior where it makes sense, but on the other hand it feels like this is an anti-pattern in that it's generally bad practise to rely on side-effects in bindings. It also feels like a misuse of
PropertyChanged
in that if that event is raised on a property that hasn't changed, a listener should be free to ignore the event.
I provided the minimal sample to simulate this behavior. In real use I need to raise the property change for the property (flags) even if its value does not change because I need to translate the flags value into another language in runtime. I do not figure out another way how to do that.
from avalonia.
ObservableCollection<T>.Count
can be binded to as it raises PropertyChanged
for Count
. Granted, that's a lot of notifications and converter calls since ObservableCollection<T>
doesn't well-support range operations.
I think stateful converters are bad practice, but I also think the ViewModel or some component in-between should be responsible for restricting notifications, if necessary.
To clarify my earlier answer: Use a IMultiValueConverter
and move the _toggle
value to the ViewModel. You bind both TestEnum
and Toggle
to the converter. Then when you mutate either one from the VM, the converter will be reevaluated and the binding target updated.
from avalonia.
Related Issues (20)
- 2-Way Binding to IObservable-like object (+XAML support) HOT 1
- Creating Popup In Code-behind HOT 1
- IBitmap is internal but the docs say it's public HOT 4
- Invoke on UI thread with `Dispatcher` causes `PlatformNotSupportedException` in `StartWithClassicDesktopLifetime`
- Make Avalonia not rely on runtime marshaling HOT 1
- add support for Rotate3DTransform in TransformOperations.Parse HOT 3
- ListBox deselects selected item when calling Move() on bound ObservableCollection
- TextBox cannot input any characters in the mobile browser Edge HOT 9
- ContextMenu HOT 3
- DataGrid editing does not change Background Color and unreadable in Dark Mode HOT 1
- `WinFormsAvaloniaControlHost` throws an exception in designer
- NumericUpDown tab index ignored on Windows HOT 2
- Menu Item InputGesture does not display when using MVVM HOT 1
- Clicking the title bar with the mouse causes frame drops and freezes HOT 3
- WindowState does not reflect correct state on Windows HOT 8
- When dragging a file onto the App window
- Context menu keyboard shortcut ignored until menu is visible at least once (Windows) HOT 2
- ILauncher is not working in browser HOT 1
- Avalonia.Browser 11.0.11 UP 11.1.0-beta2 ERROR HOT 3
- Name table parsing is incorrect HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from avalonia.