WPF DataGrid Row Style with MVVM - c#

I have a DataGrid where I'd like to change the row border color or background if a certain property of my ViewModel class is set to true. I'm having problems getting the DataTrigger to bind to the row source item (ViewModel) property. In this case, I'd like to bind to the ViewModel Property IsExpired. Unfortunately, it won't let me and throws and exception at runtime. Any help would be appreciated.
public class ViewModel
{
public uint Id { get; private set;}
public string Symbol { get; private set;}
public bool IsExpired { get; private set;}
}
public class WindowViewModel : PropertyChangedNotifier
{
public ObservableCollection<ViewModel> ViewModels { get; private set;}
private DateTime _timestamp;
public DateTime TimeStamp
{
get { return _timestamp; }
set
{
_timestamp = value;
OnPropertyChanged("TimeStamp");
}
}
}
<Grid x:Name="Layout" d:DataContext="{StaticResource DesignerViewModel}" DataContext="{Binding}">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="Accounts" VerticalAlignment="Center" Margin="5"/>
<ComboBox x:Name="AccountsComboBox" ItemsSource="{Binding Accounts}" DisplayMemberPath="ClearingNumber" Width="125"
HorizontalAlignment="Left" Margin="5" IsEditable="False" IsReadOnly="True" Style="{StaticResource AccountComboBoxStyle}"/>
<Button x:Name="LoadPositionsButton" Content="Load" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Center" Width="50" Click="LoadPositionsButtonOnClick"/>
<TextBlock x:Name="TimeStampTextBlock" HorizontalAlignment="Right" Margin="5" Width="150" Text="{Binding LastUpdate, Converter={StaticResource TimeStampConverter}}"/>
</StackPanel>
<DataGrid Grid.Row="1" ItemsSource="{Binding ViewModels}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False"
CanUserResizeRows="False" CanUserSortColumns="False" AutoGenerateColumns="False" HeadersVisibility="Column">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsExpired}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<!-- ... -->
<DataGrid.Columns>
<DataGridTemplateColumn Header="Account">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding Account}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!--<DataGridTemplateColumn Header="Exch">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding ExchangeCode}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>-->
<DataGridTemplateColumn Header="Symbol">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding Symbol}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Description">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding Description}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Maturity">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="vm:ViewModel">
<TextBlock Text="{Binding MaturityMonthYear}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGrid.Columns>
</DataGrid>
</Grid>

First you should implement INotifyPropertyChanged interface for ViewModel class. This is similar to what how you wrote in your WindowViewModel class. And then change the auto-property IsExpired to:
public bool IsExpired
{
get { return _isExpired; }
set
{
_isExpired = value;
OnPropertyChanged("IsExpired");
}
}
Second if you want to change style of certain column you should change the CellStyle property of column:
<DataGrid Grid.Row="1" ItemsSource="{Binding ViewModels}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False"
CanUserResizeRows="False" CanUserSortColumns="False" AutoGenerateColumns="False" HeadersVisibility="Column">
<DataGrid.Columns>
<DataGridTemplateColumn Header="HeaderName" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Symbol}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsExpired}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTemplateColumn.CellStyle>
</DataGridTemplateColumn>
</DataGrid.Columns>
<!-- ... -->
</DataGrid>
If you want to change style of data grid rows you should use the Template property, for example:
<DataGrid Grid.Row="1" ItemsSource="{Binding ViewModels}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False"
CanUserResizeRows="False" CanUserSortColumns="False" AutoGenerateColumns="False" HeadersVisibility="Column">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border x:Name="DataGridRowBorder"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True">
<!-- Row template -->
<Grid>
<TextBlock Text="{Binding Path=Symbol}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsExpired}" Value="True">
<Setter TargetName="DataGridRowBorder" Property="BorderBrush" Value="Red"/>
<Setter TargetName="DataGridRowBorder" Property="BorderThickness" Value="1"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowStyle>
<!-- ... -->
</DataGrid>

Related

Adding values that are in a ComboBox into a DataGrid in WPF

What I have are 4 Combo Boxes, each labelled within the dropdown menu. After that, within my code I want to setup an if else statement for the ComboBox. if the item is selected, it gets added into a DataGrid based on certain values (Cost, item Type, and name of the Item).
XAML of the ComboBox (Shortened for this question)
<TextBlock>Electronics:</TextBlock>
<ComboBox>
<ComboBoxItem x:Name="cmbxElectronics">
<TextBlock x:Name="txtLaptop">Laptop</TextBlock>
</ComboBoxItem>
<ComboBoxItem>
<TextBlock x:Name="txtPC">PC</TextBlock>
</ComboBoxItem>
<ComboBoxItem>
<TextBlock x:Name="txtStove">Stove</TextBlock>
</ComboBoxItem>
<ComboBoxItem>
<TextBlock x:Name="txtCamera">Camera</TextBlock>
</ComboBoxItem>
</ComboBox>
Here is the Data Grid XAML Code:
<StackPanel Grid.Row="0" Grid.Column="1" Margin="5">
<DataGrid Margin="5" Height="195">
<DataGrid.Columns>
<DataGridTextColumn Header=" Item" Width="*" />
<DataGridTextColumn Header=" Type" Width="*"/>
<DataGridTextColumn Header=" Cost($)" Width="*"/>
</DataGrid.Columns>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#3280fc"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="BorderThickness" Value="0,0,1,2"/>
<Setter Property="BorderBrush" Value="Black"/>
</Style>
</DataGrid.Resources>
</DataGrid>
</StackPanel>
Lastly, here is the code in the cs file which creates the class for the DataGrid (Invoice) and the Method to calculate totals (Just want to know how to set the ComboBox to the DataGrid):
private class Invoice
{
public string Item { get; set; }
public string Type { get; set; }
public double Price { get; set; }
}
private void Calculate()
{
double price = 0;
const double HST = 0.18;
if (cmbxElectronics.IsSelected)
{
}
}
Once I figure it out for one of these, the rest should be straightforward. Let me know if more information is required, Thank you.
Mainly pay attention to binding:
<DataGrid x:Name="DataGridInvoices" ItemsSource="{Binding}" Height="236" Width="636" AutoGenerateColumns="False" CanUserAddRows="False" >
<DataGrid.Columns >
<DataGridTextColumn Header=" Item" Width="*" Binding="{Binding Item}"/>
<DataGridTextColumn Header=" Type" Width="*" Binding="{Binding Type}"/>
<DataGridTextColumn Header=" Cost($)" Width="*" Binding="{Binding Price}"/>
</DataGrid.Columns>
Remove duplicate columns and remove last blank row:
AutoGenerateColumns="False" CanUserAddRows="False"
Xaml:
<Window x:Class="WpfApp5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp5"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TextBlock>Electronics:</TextBlock>
<StackPanel Grid.Row="0" Grid.Column="1" Margin="5">
<DataGrid x:Name="DataGridInvoices" ItemsSource="{Binding}" Height="236" Width="636" AutoGenerateColumns="False" CanUserAddRows="False" >
<DataGrid.Columns >
<DataGridTextColumn Header=" Item" Width="*" Binding="{Binding Item}"/>
<DataGridTextColumn Header=" Type" Width="*" Binding="{Binding Type}"/>
<DataGridTextColumn Header=" Cost($)" Width="*" Binding="{Binding Price}"/>
</DataGrid.Columns>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#3280fc"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="BorderThickness" Value="0,0,1,2"/>
<Setter Property="BorderBrush" Value="Black"/>
</Style>
</DataGrid.Resources>
</DataGrid>
</StackPanel>
<ComboBox x:Name="ComboBox1" HorizontalAlignment="Left" Margin="298,300,0,0" VerticalAlignment="Top" Width="120" SelectionChanged="ComboBox1_SelectionChanged">
<ComboBoxItem Content="Laptop"/>
<ComboBoxItem Content="PC"/>
<ComboBoxItem Content="Stove"/>
<ComboBoxItem Content="Camera"/>
</ComboBox>
</Grid>
</Window>
Code:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace WpfApp5
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Invoice invoice;
List<Invoice> Laptop = new List<Invoice>()
{
new Invoice(){Item ="0",Type="A",Price=10000},
new Invoice(){Item ="1",Type="B",Price=20000},
new Invoice(){Item ="2",Type="A",Price=15000},
};
public MainWindow()
{
InitializeComponent();
}
private class Invoice
{
public string Item { get; set; }
public string Type { get; set; }
public double Price { get; set; }
}
private void ComboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//Intercept the selected name
string sel = ComboBox1.SelectedItem.ToString();
string Rsel = sel.Substring(sel.IndexOf(" ") + 1);
if (Rsel == "Laptop")
{
DataGridInvoices.ItemsSource = Laptop;
}
}
}
}

Is it possible to replace DataGrid.GroupStyle with syncfusion:SfDataGrid?

I can't find a way to replace GroupStyle from default DataGrid control.
Styles and Templates in WPF DataGrid page says that for styling I have to use CaptionSummaryRow.
All samples from documentation about styling of group's header that I was manage to find show only how to change text's color, fonts, etc. It's not even close to what I have with default control.
What I want is DataGrid with visually separated groups but without ugly expander in headers.
MCVE
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
public SampleType[] Samples { get; } =
new[]
{
new SampleType(1, "Value1"),
new SampleType(1, "Value10"),
new SampleType(2, "Value3"),
new SampleType(3, "Value40"),
new SampleType(3, "Value50"),
new SampleType(3, "Value60"),
new SampleType(1, "Value100"),
new SampleType(1, "Value1000"),
};
}
public class SampleType
{
public SampleType(int id, string value)
{
Id = id;
Value = value;
}
public int Id { get; }
public string Value { get; }
}
<Grid>
<Grid.Resources>
<CollectionViewSource x:Key="items" Source="{Binding Samples}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Id" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<Style x:Key="GroupHeaderStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Border
Margin="0,0,0,5"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="5">
<ItemsPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<DataGrid
Grid.Row="2"
AutoGenerateColumns="False"
HeadersVisibility="Column"
IsReadOnly="True"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Source={StaticResource items}}"
SelectionMode="Single">
<DataGrid.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn
Width="20"
Binding="{Binding Id}"
Header="" />
<DataGridTextColumn
Width="*"
Binding="{Binding Value}"
Header="Value" />
</DataGrid.Columns>
</DataGrid>
</Grid>

How can I set ComboboxItem isEnable property with binding?

I have a model view and a property called isEnable and I would like to set the comboboxItem IsEnable property with binding to property created in the model view , the problem is that I have datatemplate created inside a combobox , so it's not a simple Combobox , this is my code:
<ComboBox x:Name="ComboBoxUsers" ItemsSource="{Binding Users}" FontFamily="Arial" FontSize="11" Grid.Row="3" Height="30" Margin="10,5,5,5">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Image />
<TextBlock />
</StackPanel>
<DataTemplate.Resources>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnable" Value="{Binding IsEnable}"/>
</Style>
</DataTemplate.Resources>
</DataTemplate>
</ComboBox.ItemTemplate>
Simple Class of Users:
public class Users
{
public string Name { get; set; }
public bool IsEnable { get; set; }
public Users()
{
}
}
How can I achieve that?
I solved my problem by adding this code :
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem"
<Setter Property="IsEnable" Value="{Binding IsEnable}" />
</Style>
</ComboBox.ItemContainerStyle>
So the complete code will be :
<ComboBox x:Name="ComboBoxUsers" ItemsSource="{Binding Users}" FontFamily="Arial" FontSize="11" Grid.Row="3" Height="30" Margin="10,5,5,5">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Image />
<TextBlock />
</StackPanel>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem" >
<Setter Property="IsEnable" Value="{Binding IsEnable}" />
</Style>
</ComboBox.ItemContainerStyle>
</DataTemplate>
</ComboBox.ItemTemplate>

DataGrid Cell MultiSelect ComboBox with checkboxes

I have a wpf MVVM application which shows a DataGrid. I have a few columns that are DataGridTextColumns and I want another column to be a MultiSelect Combobox in which shows a checkbox and textblock on each row. The dataSource for the datagrid is different than that of the multiselect combobox I am working towards. My Issue is that I cannot see data (list) in the multiselect combobox when its in the datagrid cell. When I move the code outside of the datagrid I am able to see data. This is my code below
ViewModel:
public class TripInfo : ViewModelBase
{
public TripInfo(bool isVisited, string cityName)
{
IsVisited = isVisited;
CityName = cityName;
}
public Boolean IsVisited { get; set; }
public String CityName { get; set; }
}
public class DataGridViewModel : ViewModelBase
{
ObservableCollection<RecordInfo> infos;
List<TripInfo> tripinfos;
ICommand _command;
public ObservableCollection<RecordInfo> PersonsInfo
{
get
{
return infos;
}
set
{
infos = value;
OnPropertyChanged("PersonsInfo");
}
}
public List<TripInfo> TripsInfo
{
get
{
return tripinfos;
}
set
{
tripinfos = value;
OnPropertyChanged("TripsInfo");
}
}
public DataGridViewModel()
{
PersonsInfo = new ObservableCollection<RecordInfo>();
TripsInfo = new List<TripInfo>();
TripsInfo.Add(new TripInfo(false, "Miami"));
TripsInfo.Add(new TripInfo(true, "Boston"));
TripsInfo.Add(new TripInfo(true, "Los Angeles"));
TripsInfo.Add(new TripInfo(true, "Houston"));
TripsInfo.Add(new TripInfo(false, "Dallas"));
TripsInfo.Add(new TripInfo(false, "Atlantic City"));
TripsInfo.Add(new TripInfo(true, "Chicago"));
GetPersonInfoData();
}
private void GetPersonInfoData()
{
PersonsInfo.Add(new RecordInfo
{
Name = "AA",
Age = 24,
DateOfBirth = new DateTime(1987, 4, 29),
Address = "XXX XXX XXXX"
});
PersonsInfo.Add(new RecordInfo
{
Name = "BB",
Age = 23,
DateOfBirth = new DateTime(1988, 3, 4),
Address = "XXX XXXXX XXX"
});
PersonsInfo.Add(new RecordInfo
{
Name = "CC",
Age = 26,
DateOfBirth = new DateTime(1985, 10, 2),
Address = "XXX XXX X"
});
View.Xaml
<Window.Resources>
<Style x:Key="NameCellStyle" TargetType="DataGridCell">
<Style.Setters>
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
<Setter Property="Background" Value="Aqua"/>
</Style.Setters>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Name="cmb" Margin="5" Height="20" ItemsSource="{Binding TripsInfo}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Margin="5" IsChecked="{Binding IsVisited}"/>
<TextBlock Margin="5" Text="{Binding CityName}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<DataGrid Grid.Row="1" Name="DGVPersonInfo" ItemsSource="{Binding PersonsInfo}" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Button Content="Remove..." Margin="3"
Command="{Binding Path=DataContext.RemoveCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Name" Binding="{Binding Name}">
<DataGridTextColumn.CellStyle>
<Style>
<Setter Property="FrameworkElement.HorizontalAlignment" Value="Center" />
<Setter Property="FrameworkElement.VerticalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Age" Binding="{Binding Age}" CellStyle="{StaticResource NameCellStyle}"/>
<DataGridTemplateColumn Header="Date Of Birth">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DateOfBirth}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding DateOfBirth}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Address" Binding="{Binding Address}" />
<DataGridTemplateColumn Header="Template">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding TripsInfo}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsVisited}" Width="20" />
<TextBlock Text="{Binding CityName}" Width="100" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
ItemSource or any property of inside a Template is not directly accessible to the DataGrid's DataContext or any other Other Control or Window.
We need to explicitly provide the data Path.
As per your Xaml Code I am not sure where you have bind your View Model, but as per your Remove Button Command, below is how your Drop Down itemSource must be bind.
<ComboBox ItemsSource="{Binding Path=DataContext.TripsInfo, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}">

how to Change Datagridcombobox cell to textbox?

I need to change the 1st cell of 1st row to a blank text box.
right now I have the column as datagridviewcombobox column?
<DataGridComboBoxColumn Header="And/Or" Width="60" ItemsSource="{Binding Source={StaticResource PredicateCombinationOperatorsEnumValues}}" SelectedItemBinding="{Binding PredicateCombinationOperator, Mode=TwoWay}" />
<DataGridComboBoxColumn Header="Field" ItemsSource="{Binding Source={StaticResource FieldTypeEnumValues}}" SelectedItemBinding="{Binding FieldType}"/>
<DataGridComboBoxColumn Header="Operator" MinWidth="70" ItemsSource="{Binding Source={StaticResource OperatorsEnumValues}}" SelectedItemBinding="{Binding Operator}"/>
<DataGridTextColumn Header="Value" MinWidth="100" Width="*" Binding="{Binding Expression}"/>
</DataGrid.Columns>
<DataGrid.InputBindings>
<KeyBinding Command="{Binding Source={StaticResource DeleteContextMenuCommand}}" Key="Delete"/>
</DataGrid.InputBindings>
<DataGrid.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuOptions}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Name}" />
<Setter Property="Command" Value="{Binding}" />
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}" />
<Setter Property="AutomationProperties.AutomationId" Value="{Binding Name}" />
<Setter Property="AutomationProperties.Name" Value="{Binding Name}" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</DataGrid.ContextMenu>
<i:Interaction.Triggers>
<i:EventTrigger EventName="ContextMenuOpening">
<trigger:ContextMenuOpeningTriggerAction/>
</i:EventTrigger>
<i:EventTrigger EventName="SelectionChanged">
<trigger:SelectionChangeTriggerAction/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
You could specify conditional data template and select the template according to your condition. First we have to inherit class from DataTemplateSelector and define properties of DataTemplate type. Define as much properties as data template you want.Then override the SelectTemplate method to return the datatemplate you want.Check the below sample code
<Window.Resources>
<local:Animals x:Key="animals"/>
<DataTemplate x:Key="TextTemplate">
<TextBox Margin="2" Width="60" />
</DataTemplate>
<DataTemplate x:Key="ComboTemplate" >
<ComboBox Width="60" />
</DataTemplate>
</Window.Resources>
<Grid>
<Controls:DataGrid>
<Controls:DataGrid.Columns>
<Controls:DataGridTemplateColumn Header="And/Or" Width="60">
<Controls:DataGridTemplateColumn.CellTemplateSelector>
<local:CustomTemplateSelector
TextTemplate="{StaticResource TextTemplate}"
ComboTemplate="{StaticResource ComboTemplate}"/>
</Controls:DataGridTemplateColumn.CellTemplateSelector>
</Controls:DataGridTemplateColumn>
<Controls:DataGridComboBoxColumn Header="Field"/>
<Controls:DataGridComboBoxColumn Header="Operator" MinWidth="70" />
<Controls:DataGridTextColumn Header="Value" MinWidth="100" Width="*"/>
</Controls:DataGrid.Columns>
</Controls:DataGrid>
</Grid>
public class CustomTemplateSelector : DataTemplateSelector
{
public DataTemplate TextTemplate
{ get; set; }
public DataTemplate ComboTemplate
{ get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
MyObject obj = item as MyObject;
if (obj != null)
{
// custom logic to select appropriate data template and return
}
else
return base.SelectTemplate(item, container);
}
}
}
for more check here
http://zamjad.wordpress.com/2010/08/23/apply-conditional-data-template-in-data-grid/

Categories

Resources