Goal
I currently have an app that select the items only by selecting the check box. Like so:
My goal is to multi select items (Which highlights the selected rows), right click and have a data context menu item to select, selected items.
Desired Output
As an example, this would be my desired output (Obviously not selecting the checkboxes manually).
Question
What would a good starting point to achieve this output? I couldn't find any examples.
Code
The Model is pretty simple.
public class OrdersModel : BaseVM
{
public int OrderId { get; set; } // Hidden
public string OrderNumber { get; set; }
public DateTime OrderDate { get; set; }
private bool _selectedRecord;
public bool SelectedRecord
{
get { return _selectedRecord; }
set
{
_selectedRecord = value;
OnPropertyChanged();
}
}
}
And this is my current XAML.
<DataGrid ItemsSource="{Binding Orders}"
AutoGenerateColumns="False"
SelectionMode="Extended"
CanUserAddRows="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=SelectedRecord}" Value="True">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<!--Columns Used-->
<DataGrid.Columns>
<!--Select All Column-->
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Content="Select All"
IsChecked="{Binding DataContext.SelectAll, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"
Command="{Binding DataContext.ToggleAllOrdersCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=SelectedRecord, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Order Date"
Binding="{Binding OrderDate, StringFormat='{}{0:MM-dd-yyyy}'}" Width="*"
IsReadOnly="True"
FontSize="14" />
<DataGridTextColumn Header="Order Number"
Binding="{Binding OrderNumber}" Width="*"
IsReadOnly="True"
FontSize="14" />
</DataGrid.Columns>
<!--Menu Options-->
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Select Highlighted Rows" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
This solution worked for me. I took the liberty of changing some of your property names to avoid confusion as to what is "selected" and what is "checked".
OrdersModel:
public class OrdersModel : BaseVM
{
public int OrderId { get; set; } // Hidden
public string OrderNumber { get; set; }
public DateTime OrderDate { get; set; }
private bool _selected;
private bool _checked;
public bool Selected
{
get { return _selected; }
set { _selected = value; OnPropertyChanged(); }
}
public bool Checked
{
get { return _checked; }
set { _checked = value; OnPropertyChanged(); }
}
}
MainWindow.xaml.cs
<DataGrid ItemsSource="{Binding Orders}"
AutoGenerateColumns="False"
SelectionMode="Extended"
CanUserAddRows="False"
Tag="{Binding ElementName=myWindow,Path=DataContext}"
>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="IsSelected" Value="{Binding Selected}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Selected}" Value="True">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<!--Columns Used-->
<DataGrid.Columns>
<!--Select All Column-->
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Content="Select All"
IsChecked="{Binding DataContext.SelectAll, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"
Command="{Binding DataContext.ToggleAllOrdersCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=Checked, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Order Date"
Binding="{Binding OrderDate, StringFormat='{}{0:MM-dd-yyyy}'}" Width="*"
IsReadOnly="True"
FontSize="14" />
<DataGridTextColumn Header="Order Number"
Binding="{Binding OrderNumber}" Width="*"
IsReadOnly="True"
FontSize="14" />
</DataGrid.Columns>
<!--Menu Options-->
<DataGrid.ContextMenu>
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Select Highlighted Rows" Command="{Binding CheckSelectedCommand}"/>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
MainWindow.xaml.cs:
public class MainWindowViewModel : BaseVM
{
private ObservableCollection<OrdersModel> _orders;
private RelayCommand _checkSelectedCommand;
public MainWindowViewModel()
{
Initialize();
}
public ObservableCollection<OrdersModel> Orders
{
get
{
if (_orders == null)
_orders = new ObservableCollection<OrdersModel>();
return _orders;
}
}
public RelayCommand CheckSelectedCommand
{
get
{
if (_checkSelectedCommand == null)
_checkSelectedCommand = new RelayCommand(o => DoCheckSelectedRows());
return _checkSelectedCommand;
}
}
public void Initialize()
{
var dateTime = DateTime.Now.AddDays(-5);
for (int i = 0; i < 10; i++)
{
this.Orders.Add(new OrdersModel() { OrderId = i, OrderDate = dateTime.AddHours(4), OrderNumber = $"CA{i + 1593:0000}" });
}
}
private void DoCheckSelectedRows()
{
var selectedOrders = this.Orders.Where(o => o.Selected);
foreach (var order in selectedOrders)
{
order.Checked = true;
}
}
}
Solution will look like this:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.