绑定到 DataGrid 的 SelectedItems 不通知目标

Bound-to DataGrid's SelectedItems not Notifying Target

我正在将 ButtonIsEnabled 属性 绑定到 DataGridSelectedItems 的数量。

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 事件正常触发,但是按钮永远不会收到选择更改的通知,我可能在这里遗漏了什么?

对于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 方法,用于启用和禁用按钮。您不需要对按钮使用交互触发器,因为它已经将命令 属性 关联到单击事件。参考下面的代码。

 <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;
    }

}