Привязанные к DataGrid выбранные элементы не уведомляют цель

1

Я привязываю свойство IsEnabled Button к числу SelectedItems DataGrid.

XAML:

<DataGrid SelectionChanged="DG_Reports_OnSelectionChanged" x:Name="DG_Reports" SelectionMode="Extended" ItemsSource="{Binding Reportslists, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=Explicit}" AutoGenerateColumns="False" CanUserAddRows="True" CanUserReorderColumns="False" CanUserDeleteRows="True">
        <DataGrid.RowHeaderTemplate>
              <DataTemplate>
                   <Grid>
                         <CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGridRow}}}"/>
                   </Grid>
              </DataTemplate>
        </DataGrid.RowHeaderTemplate>            
        <DataGrid.Columns>
             <!-- Columns Here -->
        </DataGrid.Columns>
</DataGrid>

<Button x:Name="Bt_RemoveReports" Content="Supprimer Rapport" IsEnabled="{Binding ElementName=DG_Reports, NotifyOnSourceUpdated=True, Path=SelectedItems, Converter={StaticResource SelectedDataGridRowsToBooleanConverter}}">
        <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                      <command:EventToCommand Command="{Binding DeleteReports}" CommandParameter="{Binding ElementName=DG_Reports, Path=SelectedItems}"/>
                </i:EventTrigger>
        </i:Interaction.Triggers>
</Button>

Конвертер SelectedDataGridRowsToBooleanConverter:

public class SelectedDataGridRowsToBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((IList<Object>) value).Count > 0;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

В начале (означает, что в DataGrid ничего не выбрано), кнопка успешно не включена, но как только я начинаю выбирать строки, ничего не происходит, я должен отметить, что событие DataGrid SelectionChanged срабатывает нормально, но кнопка никогда не уведомляется об изменении в выборе, что я могу здесь пропустить?

Теги:
xaml
wpf
data-binding
datagrid

1 ответ

1
Лучший ответ

Для DataGrid SelectedItems - это коллекция и не может использоваться, как указано выше. Вместо этого вы можете использовать SelectedItems.Count и изменить конвертер, как указано ниже.

 <Button x:Name="Bt_RemoveReports" Content="Supprimer Rapport" IsEnabled="{Binding ElementName=DG_Reports, 
        NotifyOnSourceUpdated=True, Path=SelectedItems.Count, Converter={StaticResource SelectedDataGridRowsToBooleanConverter}}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <command:EventToCommand Command="{Binding DeleteReports}" CommandParameter="{Binding ElementName=DG_Reports, Path=SelectedItems}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>
public class SelectedDataGridRowsToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (int)value > 0;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Другой способ достичь этой функциональности. В этом вам нужно написать конвертер. Команда CanExecute метод с разрешением включения и отключения кнопки. Вам не нужно использовать триггеры взаимодействия для кнопок, поскольку у него уже есть свойство Command, связанное с событием click. См. Ниже код.

 <StackPanel>        
    <DataGrid x:Name="DG_Reports" Height="200"
            AutoGenerateColumns="False"                
            ItemsSource="{Binding SampleItems}" >
        <DataGrid.RowHeaderTemplate>
            <DataTemplate>
                <Grid>
                    <CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay,
                        RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGridRow}}}"/>
                </Grid>
            </DataTemplate>
        </DataGrid.RowHeaderTemplate>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Date" Binding="{Binding DayOfMonth}">                   
            </DataGridTextColumn>
            <DataGridTextColumn Header="Day" Binding="{Binding Weekday}">                    
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
    <Button x:Name="Bt_RemoveReports" Content="Supprimer Rapport" Command="{Binding DeleteReports}"
            CommandParameter="{Binding ElementName=DG_Reports, Path=SelectedItems}">            
    </Button>
</StackPanel>   

 public class Item
{
    public int DayOfMonth { get; set; }
    public string Weekday { get; set; }
}

public class MainViewModel 
{
    private ObservableCollection<Item> m_items;
    public ObservableCollection<Item> SampleItems
    {
        get { return m_items; }
        set { m_items=value; }
    }

    public ICommand DeleteReports { get; private set; }

    public MainViewModel()
    {
        DeleteReports = new RelayCommand<object>(Delete,CanDelete);

        var items = new ObservableCollection<Item>();
        var today = DateTime.Now;
        for (int i = 1; i <= DateTime.DaysInMonth(today.Year, today.Month); i++)
        {
            items.Add(new Item { DayOfMonth = i, Weekday = new DateTime(today.Year, today.Month, i).DayOfWeek.ToString() });
        }
        SampleItems = items;
    }

    private void Delete(object obj)
    {
        var items = new ObservableCollection<Item>();
        foreach (var item in (IList)obj)
        {
            items.Add((Item)item);
        }
        foreach (var item in items)
        {
            m_items.Remove(item);
        }
    }

    private bool CanDelete(object obj)
    {
        return ((IList)obj).Count > 0;
    }

}
  • 0
    Спасибо за ваш ответ, действительно, вы правы, все еще не понимаете, почему мой код не работает, почему SelectedItems не уведомит цель привязки? Можете ли вы объяснить это, пожалуйста?
  • 0
    SelectedItems имеет тип IList, и IList не реализует какой-либо механизм уведомления.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню