Bonjour,
J'ai un objet métier qui implémente INotifyPropertyChanged.
Cet objet a une propriété IsSelected qui prévient correctement sa modification.
Je donne comme source à un datagrid une ICollectionView remplit de mon objet métier.
Je redéfinis le style de DataGridRow pour bind la propriété IsSelected de l'objet métier à celle du DataGridRow, ainsi sur selection des lignes de ma datagrid, mes objets en son informé.
J'ai un bouton sur lequel je veux bind la propriété IsEnabled sur ma collection à l'aide d'un convertisseur qui retourne True ou False si une propriété IsSelected d'un des objets métiers de la collection est à True.
Tout fonctionne bien, sauf que quand je selectionne une ligne, la propriété IsSelected de l'objet associé est bien miste à True, mais le binding sur IsEnabled de mon bouton n'est pas réévalué.
Comment faire en sorte que la collection notify ce changement ?
Objet métier implémentant INotifyPropertyChanged
DataGrid
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 private bool isSelected; [Browsable(false)] public bool IsSelected { get { return isSelected; } set { isSelected = value; OnPropertyChanged("IsSelected"); } }
Bouton
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 <my1:Tableau ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type parametrage:ParametrageSimple}}, Mode=OneWay}" SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type parametrage:ParametrageSimple}}, Mode=TwoWay}" AutoGenerateColumns="True" HorizontalAlignment="Stretch" x:Name="extendedDataGrid1" VerticalAlignment="Stretch" Margin="0,0,33,30" MinHeight="180" SelectionMode="Extended" CanUserSortColumns="False" IsReadOnly="True" ColumnWidth="*" > <my1:Tableau.ItemContainerStyle> <Style> <Setter Property="DataGridRow.IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> </Style> </my1:Tableau.ItemContainerStyle> </my1:Tableau>
Chargement de la collection
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 <boutons:BoutonIconeSupprimer IsEnabled="{Binding ItemsSource, Converter={converters:CollectionHaveSelectedToBoolConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:UCParametrageTableau}}, Mode=OneWay}" Name="btnIconeSupprimer" VerticalAlignment="Center" Grid.Row="2" Margin="0,5" />
Convertisseur
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 public static DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(ICollectionView), typeof(ParametrageSimple), new PropertyMetadata(null)); public ICollectionView ItemsSource { get { return (ICollectionView)(GetValue(ItemsSourceProperty)); } set { SetValue(ItemsSourceProperty, value); } } public static DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(Object), typeof(ParametrageSimple), new PropertyMetadata(null)); public Object SelectedItem { get { return (GetValue(SelectedItemProperty)); } set { SetValue(SelectedItemProperty, value); } } ... ItemsSource = CollectionViewSource.GetDefaultView(new List<BrancheVM>()); foreach (var item in serviceBranche.GetAll(AccesApplication.AccesApplication, null)) (ItemsSource as ListCollectionView).AddNewItem(new BrancheVM(item)); (ItemsSource as ListCollectionView).CommitNew();
Merci pour votre aide.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 class CollectionHaveSelectedToBoolConverter : MarkupExtension, IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if ((value as ICollectionView) != null) { return LookForSelected(value as ICollectionView); } return false; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return null; } public bool LookForSelected(ICollectionView source) { bool haveSelected = false; if (source != null) foreach (var item in source) { if (haveSelected) break; if ((item as IHierarchical) != null) if (haveSelected = LookForSelected((item as IHierarchical).Childs)) break; if ((item as ISelected) != null) haveSelected = (item as ISelected).IsSelected; } return haveSelected; } private static CollectionHaveSelectedToBoolConverter converter = null; public override object ProvideValue(IServiceProvider serviceProvider) { if (converter == null) converter = new CollectionHaveSelectedToBoolConverter(); return converter; } }
PS : Je peux évidement passer par une ICommand, ce qui fonctionne très bien, cependant, je n'ai pas l'air de maitriser quand est ce que la commande re-évalue la méthode canExecute, ce qui me gène un peu quand il s'agit d'évaluer une collection entière.
Partager