Reputation: 8301
I am binding the IsEnabled
Property of a Button
to the number of SelectedItems
of a 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>
The SelectedDataGridRowsToBooleanConverter Converter :
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();
}
}
In the beginning (Means when nothing is selected in the DataGrid) the Button is successfully Not Enabled, but once I start selecting rows, nothing happens, I should note that the DataGrid's SelectionChanged
event fires normally, but the button is never notified of the changing in selection, what may I be missing here ?
Upvotes: 1
Views: 349
Reputation: 5366
For DataGrid SelectedItems is a collection and cannot be used like above. Instead you can use SelectedItems.Count and change the converter as mentioned below.
<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();
}
}
Other way of achieve this functionality. In this you need to write converter. Command's CanExecute method with take of enabling and Disabling of the button. You need not to use Interaction triggers for buttons since it already has Command property associated to click event. Refer below code.
<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;
}
}
Upvotes: 1