Change button tooltip with style - WPF - c#

I have a DataGrid loaded with a list of objects that have a property bool IsAutomaticSell. I need that when changing the value, the tooltip of the button of that row is updated. I have the following code but it does not work. Thx
View.xaml
<DataGridTextColumn Header="Code"
Binding="{Binding Code}" />
<DataGridTemplateColumn Header="Actions"
Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Command="{Binding DataContext.AutomaticSellCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}"
Padding="10"
Margin="0,2,2,2">
<iconPacks:PackIconModern Kind="CurrencyDollar" />
<Button.Style>
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource AccentedSquareButtonStyle}">
<Setter Property="ToolTip"
Value="DEFAULT_TOOLTIP" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsAutomaticSell, UpdateSourceTrigger=PropertyChanged}"
Value="True">
<Setter Property="ToolTip"
Value="NEW_TOOLTIP" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
ViewModel.cs
public ICommand AutomaticSellCommand => _automaticSellCommand ??
(_automaticSellCommand = new RelayCommand<OrderStatusDataWrapper>(AutomaticSell));
private static void AutomaticSell(OrderStatusDataWrapper orderStatusData)
{
orderStatusData.IsAutomaticSell = !orderStatusData.IsAutomaticSell;
}

Bind ToolTip.
XAML:
<Button ToolTip={Binding ToolTip}" ... />
ViewModel:
public string ToolTip => (IsAutomaticSell) ? "DEFAULT_TOOLTIP" : "NEW_TOOLTIP";

You need to implement a ValueConverter in order to get this to work.
A ValueConverter will allow you to handle what to display based on your boolean value.
MSDN
public class BoolToContentConverter : IValueConverter
{
public BoolToContentConverter()
{
TrueContent = "True Tool Tip";
FalseContent = "False Tool Tip";
NullContent = "No Value";
}
public object TrueContent { get; set; }
public object FalseContent { get; set; }
public object NullContent { get; set; }
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (value == null)
return NullContent;
bool boolValue = true;
bool isBool = true;
try
{
boolValue = (bool) value;
}
catch
{
isBool = false;
}
if (!isBool)
return NullContent;
return boolValue ? TrueContent : FalseContent;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
In your XAML you need to implement that converter.
<Window x:Class="Example.MainWindow"
...
xmlns:l="clr-Example"
...>
<Window.Resources>
<l:BoolToContentConverter x:Key="converter" />
</Window.Resources>
...
<DataGridTextColumn Header="Code"
Binding="{Binding Code}" />
<DataGridTemplateColumn Header="Actions"
Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Command="{Binding DataContext.AutomaticSellCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}"
Padding="10"
Margin="0,2,2,2">
<iconPacks:PackIconModern Kind="CurrencyDollar" />
<Button.Style>
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource AccentedSquareButtonStyle}">
<Setter Property="ToolTip"
Value="DEFAULT_TOOLTIP" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsAutomaticSell, UpdateSourceTrigger=PropertyChanged}"
Value="True">
<Setter Property="ToolTip"
Value="{Binding IsAutomaticSell, Converter={StaticResource converter}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
....
</Window>
Hope this answers your question. Cheers!

Related

DataTrigger binded to property in ViewModel is not fired in the Button of DataGrid

I've created ControlTemplates:
<Window.Resources>
<ControlTemplate x:Key="imgNo" TargetType="{x:Type Control}">
<Image Source="pack://application:,,,/Images/up.png"/>
</ControlTemplate>
<ControlTemplate x:Key="imgUp" TargetType="{x:Type Control}">
<!--<TextBlock Text="Up"/>-->
<Image Source="pack://application:,,,/Images/up.png"/>
</ControlTemplate>
<ControlTemplate x:Key="imgDown" TargetType="{x:Type Control}">
<Image Source="pack://application:,,,/Images/downArrow.png"/>
</ControlTemplate>
<DataTemplate x:Key="ButtonOneDataTemplate">
<Control x:Name="theControl" Template="{DynamicResource imgNo}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsImageChanged}" Value="true">
<Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgUp}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsImageChanged}" Value="false">
<Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgDown}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</WindowResources>
and Button in DataGrid which uses above ControlTemplates:
<DataGrid ItemsSource="{Binding Persons}" Grid.Row="1" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding IdPerson}">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<Border Background="Violet">
<StackPanel>
<Button ContentTemplate="{StaticResource ButtonOneDataTemplate}"
Command="{Binding DataContext.HelloCommand, RelativeSource=
{RelativeSource AncestorType=Window}}"
CommandParameter="{Binding DataContext.Hello,
RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</StackPanel>
</Border>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
My ViewModel:
public class MainWindowViewModel:ViewModelBase
{
public RelayCommand HelloCommand { get; set; }
public MainWindowViewModel()
{
LoadPersons();
HelloCommand = new RelayCommand(SayHello);
}
int helloCounter = 0;
private void SayHello(object obj)
{
if (helloCounter % 2 == 0)
IsImageChanged = true;
else
IsImageChanged = false;
helloCounter++;
}
private bool isImageChanged=true;
public bool IsImageChanged
{
get { return isImageChanged; }
set { isImageChanged = value;
OnPropertyChanged("IsImageChanged");
}
}
}
What I want is when I click on the button <Button ContentTemplate="{StaticResource ButtonOneDataTemplate}"/>, then Template should be replaced to {DynamicResource imgDown} or {DynamicResource imgUp}. DataTrigger depends on IsImageChanged value.
However, if I click on the Button, then DataTrigger is not fired(Controltemplates such as imgUp, imgDown are not changed). How can I achieve this from my ViewModel?
Problem is that DataGrid column is not a part of a visual tree, and because of that it does not inherit DataContext. To be able to use DataTriggers in your ButtonOneDataTemplate you need that button, you applying this template to, has correct DataContext. There is a trick, how to provide DataContext to elements that are not in VisualTree, described here
Applying that solution to your code we'll have the following:
Proxy
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
Window.Resources
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
<DataTemplate x:Key="ButtonOneDataTemplate">
<Control x:Name="theControl" Template="{DynamicResource imgNo}" Foreground="Orange"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.IsImageChanged}" Value="True">
<Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgUp}" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.IsImageChanged}" Value="False">
<Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgDown}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
HeaderTemplate
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<Border Background="Violet">
<StackPanel>
<Button ContentTemplate="{StaticResource ButtonOneDataTemplate}"
DataContext="{Binding Path=Data, Source={StaticResource proxy}}"
Command="{Binding DataContext.ButtonClick, RelativeSource={RelativeSource AncestorType=Window}}"
CommandParameter="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</StackPanel>
</Border>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>

Styling DataGrid rows WPF exception

I'm trying to style my grid a little bit. I want to color rows based on information in the each row. I've got this nasty error during this operation. Moreover this is happening during application startup. This my first steps in WPF I'm trying to make some useful logger, but now I hit the huge wall.
Error:
Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.
It is worth mentioning that I'm using static list as ItemSource to grid. Below some code of mine.
<DataGrid DockPanel.Dock="Bottom" Height="Auto" ItemsSource="{Binding Source={x:Static Log:Logger.LogCollection}, Mode=OneWay}" FontSize="12" FontFamily="Segoe UI">
<i:Interaction.Behaviors>
<fw:ScrollGridView/>
</i:Interaction.Behaviors>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding LogType}" Value="Info">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid>
</DockPanel>
And the class
public static class Logger
{
private static ObservableCollection<LogMessage> _logCollection = new ObservableCollection<LogMessage>();
public static ObservableCollection<LogMessage> LogCollection
{
get { return Logger._logCollection; }
set
{
if (_logCollection.Count > 500)
{
_logCollection.RemoveAt(_logCollection.Count - 1);
}
Logger._logCollection = value;
}
}
public static void Log(string message)
{
Log(LogType.Info, message, null);
}
public static void Log(LogType type, string message, string exception)
{
LogCollection.Add(new LogMessage { Type = type, Time = DateTime.Now, Message = message, Exception = exception });
}
}
LogMessage:
public enum LogType
{
Debug,
Warning,
Error,
Info
}
public class LogMessage
{
public LogType Type { get; set; }
public DateTime Time { get; set; }
public string Message { get; set; }
public string Exception { get; set; }
}
Thanks!
Make sure you define your Columns for DataGrid in DataGrid.Columns like below and not directly within DataGrid and define your Style in DataGrid.Resource
<DataGrid>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding LogType}" Value="Info">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn/>
</DataGrid.Columns>
</DataGrid>
It helped!!! Now it looks like this:
<DataGrid DockPanel.Dock="Bottom" Height="Auto" ItemsSource="{Binding Source={x:Static Log:Logger.LogCollection}, Mode=OneWay}" FontSize="12" FontFamily="Segoe UI" AutoGenerateColumns="False">
<i:Interaction.Behaviors>
<fw:ScrollGridView/>
</i:Interaction.Behaviors>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Type}" Value="Info">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn MinWidth="30" Header="Type">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Width="16"
Height="16"
Source="{Binding Path=Type,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource ImageTypeConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Time"
Binding="{Binding Time}"/>
<DataGridTextColumn Header="Message"
Binding="{Binding Message}"
Width="1200">
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Exception"
Binding="{Binding Exception}"
Width="1200">
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
And I have another one question. Before I have added DataGrid.Resources my behavior worker perfectly and after that the event stopped firing. It is strange because I didn't change way of adding item to my grid source.
public class ScrollGridView : Behavior<DataGrid>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectionChanged += new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
}
private void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is DataGrid)
{
DataGrid grid = (sender as DataGrid);
if (grid.Items.Count > 0)
{
var border = VisualTreeHelper.GetChild(grid, 0) as Decorator;
if (border != null)
{
var scroll = border.Child as ScrollViewer;
if (scroll != null && !scroll.IsMouseOver) scroll.ScrollToEnd();
}
}
}
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.SelectionChanged -= new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
}
}

Change ContentPresenter's DataTemplate

I have a popup, where I want to display different things depending on various buttons which are clicked. To do this I've added a ContentPresenter nad in this ContentPresenter I've got an TemplateSelector. My problem is that as far as I can see it only checks which template to use the first time my popUp is run and uses this template from then on. Is there a way to get the code to change the template to use?
The code I've got so far is (xaml):
<Popup IsOpen="{Binding IsOpen}" Height="{Binding Height}" Width="{Binding Width}">
<Grid>
<ContentPresenter x:Name="CP" Loaded="CP_Loaded">
<ViewModel:PopUpTemplateSelector x:Name="PUT" Content="{Binding}">
<ViewModel:PopUpTemplateSelector.View1>
<DataTemplate>
<View:View1/>
</DataTemplate>
</ViewModel:PopUpTemplateSelector.View1>
<ViewModel:PopUpTemplateSelector.View2>
<DataTemplate>
<View:View2/>
</DataTemplate>
</ViewModel:PopUpTemplateSelector.View2>
<ViewModel:PopUpTemplateSelector.View3>
<DataTemplate>
<View:View3/>
</DataTemplate>
</ViewModel:PopUpTemplateSelector.View3>
<ViewModel:PopUpTemplateSelector.View4>
<DataTemplate>
<View:View4/>
</DataTemplate>
</ViewModel:PopUpTemplateSelector.View4>
<ViewModel:PopUpTemplateSelector.View5>
<DataTemplate>
<Design:View5/>
</DataTemplate>
</ViewModel:PopUpTemplateSelector.View5>
</ViewModel:PopUpTemplateSelector>
</ContentPresenter>
</Grid>
</Popup>
and my popUpTemplateSelector(C#) is
public class PopUpTemplateSelector : DataTemplateSelector
{
public DataTemplate View1{ get; set; }
public DataTemplate View2 { get; set; }
public DataTemplate View3 { get; set; }
public DataTemplate View4 { get; set; }
public DataTemplate View5 { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
PopUpViewModel Pop = item as PopUpViewModel;
if(Pop.TemplateToUse == "View1")
{
return View1;
}
else if(Pop.TemplateToUse == "View2")
{
return View2;
}
else if(Pop.TemplateToUse.Equals("View3"))
{
return View3;
}
else if (Pop.TemplateToUse.Equals("View4"))
{
return View4;
}
else if(Pop.TemplateToUse.Equals("View5"))
{
return View5;
}
return null;
}
}
I would suggest you use DataTriggers bound to TemplateToUse property on the ViewModel to update ContentTemplate. And also use ContentControl instead of ContentPresenter
<Popup IsOpen="{Binding IsOpen}" Height="{Binding Height}" Width="{Binding Width}">
<Grid>
<Grid.Resources>
<DataTemplate x:Key="View1Template">
<View:View1/>
</DataTemplate>
<DataTemplate x:Key="View2Template">
<View:View2/>
</DataTemplate>
<DataTemplate x:Key="View3Template">
<View:View3/>
</DataTemplate>
<DataTemplate x:Key="View4Template">
<View:View4/>
</DataTemplate>
<DataTemplate x:Key="View5Template">
<Design:View5/>
</DataTemplate>
<Style x:Key="ContentStyle" TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=TemplateToUse}" Value="View1">
<Setter Property="ContentTemplate" Value="{StaticResource View1Template}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=TemplateToUse}" Value="View2">
<Setter Property="ContentTemplate" Value="{StaticResource View2Template}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=TemplateToUse}" Value="View3">
<Setter Property="ContentTemplate" Value="{StaticResource View3Template}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=TemplateToUse}" Value="View4">
<Setter Property="ContentTemplate" Value="{StaticResource View4Template}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=TemplateToUse}" Value="View5">
<Setter Property="ContentTemplate" Value="{StaticResource View5Template}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<ContentControl x:Name="CP" Loaded="CP_Loaded" Style="{StaticResource ContentStyle}" Content="{Binding}" />
</Grid>
</Popup>

Disable ValidatesOnDataErrors if CheckBox is Checked WPF

I am trying to disable ValidatesOnDataErrors on a TextBox if a certain checkbox is checked.
I have tried placing a trigger on textbox to enable or disable validation based on the checkbox seems like the trigger gets hit but does not disable validation. I am using IDataErrorInfo for validation in the .cs code. Here is the code I have tried, this has been a headache so hope you can help.
.xaml
<TextBox Name="txtFoundERTReading" Height="23" Canvas.Left="125" TextWrapping="Wrap" Canvas.Top="136" Width="120">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cbFoundERTReading, Path=IsChecked}" Value="False">
<Setter Property="Text" Value="{Binding Found.ERTReading, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=cbFoundERTReading, Path=IsChecked}" Value="True">
<Setter Property="TextBox.IsEnabled" Value="False" />
<Setter Property="Text" Value="{Binding Found.ERTReading, Mode=TwoWay, ValidatesOnDataErrors=False, UpdateSourceTrigger=PropertyChanged}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Instead of changing the ValidatesOnDataErrors property at run time, the best approach is to have a boolean property in viewmodel and do validation only if it is true. The boolean property can bound to IsChecked property of a Checkbox.
public string Name
{
get { return name; }
set { name = value; RaisePropertyChanged("Name"); }
}
public string this[string columnName]
{
get
{
if (CanValidate)
{
if (columnName == "Name")
{
if (!ValidateName())
{
return "Error";
}
}
}
return "";
}
}
private bool canValidate;
public bool CanValidate
{
get { return canValidate; }
set { canValidate = value; RaisePropertyChanged("CanValidate"); RaisePropertyChanged("Name");}
}
private bool ValidateName()
{
if (String.IsNullOrEmpty(Name))
{
return false;
}
return true;
}
The XAML looks like below,
<StackPanel>
<TextBox Margin="5" Text="{Binding Name, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}"/>
<CheckBox Margin="5" Content="Can validate" IsChecked="{Binding CanValidate, Mode=TwoWay}"/>
</StackPanel>
Use this,
Validation.ErrorTemplate="{x:Null}"

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