WPF - Button IsEnabled Binding Converter
Question
I have an ObservableCollection<MyEntity>
and MyEntity
has a IsChecked
property with a PropertyChanged
event.
I have a Button
and I would like to change IsEnabled
property to true
when at least one of MyEntity
of the MyObservableCollection
is checked.
I created a converter which takes the ObservableCollection
and return true when a MyEntity
is checked at least.
But the return "null"
is returned.
What is wrong ? Thank you for your help.
XAML
<Window.Resources>
<CollectionViewSource x:Key="MyObservableCollection"/>
<src:MyConverter x:Key="MyConverter"/>
</Window.Resources>
<Button IsEnabled="{Binding Converter={StaticResource MyConverter}, Source={StaticResource MyObservableCollection}}"/>
C# Converter
class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (null == value)
return "null";
ReadOnlyObservableCollection<object> items = (ReadOnlyObservableCollection<object>)value;
List<MyEntity> myEntities = (from i in items select (MyEntity)i).ToList();
foreach (MyEntity entity in myEntities)
{
if (entity.IsChecked)
{
return true;
}
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
La solution
I think your Binding is wrong. The Converter want's the underlying collection not the CollectionView
. And set the CollectionViewSource.Source
after InitializeComponent()
, the Binding will be refreshed.
<Button IsEnabled="{Binding Path=SourceCollection,
Converter={StaticResource MyConverter},
Source={StaticResource MyObservableCollection}}" />
Autres conseils
Since StaticResources are resolved at the time of intializing itself i.e. at the time of InitializeComponent()
but till that time your collection is yet not intialized that's why null value is passed to the converter.
So, better choice would be to move that property in your code behind and bind to that property since binding will be resloved after InitializeComponent()
. Create property in your code-behind-
public CollectionViewSource MyObservableCollection { get; set; }
and bind to your button -
<Button IsEnabled="{Binding MyObservableCollection, RelativeSource=
{RelativeSource AncestorType=Window}, Converter={StaticResource MyConverter}}"/>