سؤال

I want to change the content of a DataGridCell. I have a column in the datagridview like so

<DataGridCheckBoxColumn CellStyle="ChangeContentOfCellSstyle"...

Then I have a DataTrigger like so:

<Style TargetType="DataGridCell" x:Key="ChangeContentOfCellSstyle">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsWashed}" Value="True">
            <Setter Property="Content" Value="The new value for the cell."/> 
            <Setter Property="Background" Value="Red"/> //sets the background of the cell to red just to show the trigger is working
        </DataTrigger>
    </Style.Triggers>
</Style>

But the content of the cell is not changing. Not even when I try the same with a DataGridTextColumn although the cell turns red.

هل كانت مفيدة؟

المحلول

I've removed my previous answer since using a template selector is a much better way of doing this.

first I create a DataTemplateSelector class that can be used to switch between DataTemplates based on a binding, note the 2 properties that take in references to the styles that will be applied, I could have used find resource here but I think this is cleaner and doesn't require view designers to stick to hard coded template keys.

public class IsWashedStyleSelector : DataTemplateSelector
{

    public DataTemplate TrueStyle { get; set; }
    public DataTemplate FalseStyle { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        TestClass targetItem = item as TestClass;
        if (targetItem != null)
        {
            return targetItem.IsWashed ? TrueStyle : FalseStyle;
        }
        return base.SelectTemplate(item, container);
    }
}

Now to use this template selector I have to define 2 data templates and also instance the selector in xaml resources.

<DataTemplate x:Key="styleIsWashedTrue">
    <Button>It's true</Button>
</DataTemplate>
<DataTemplate x:Key="styleIsWashedFalse">
    <Label>is false</Label>
</DataTemplate>

<local:IsWashedStyleSelector x:Key="isWashedStyleSelector"  TrueStyle="{StaticResource styleIsWashedTrue}" FalseStyle="{StaticResource styleIsWashedFalse}"/>

Finally the selector can be used in a DataGridTemplateColumn like so.

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridCheckBoxColumn Binding="{Binding IsWashed}"/>
            <DataGridTextColumn Binding="{Binding Text}"/>
            <DataGridTemplateColumn CellTemplateSelector="{StaticResource isWashedStyleSelector}"/>
        </DataGrid.Columns>
    </DataGrid>

نصائح أخرى

This answer is really a comment on @Andy's answer. It seems I can't format code in a comment.

Note that you can inline the DataTemplate definitions in your XAML, to put everything all together in one place.

<local:IsWashedStyleSelector x:Key="isWashedStyleSelector">
  <local:IsWashedStyleSelector.TrueStyle>
    <DataTemplate>
      <Button>It's true</Button>
    </DataTemplate>
  </local:IsWashedStyleSelector.TrueStyle>
  <local:IsWashedStyleSelector.FalseStyle>
    <DataTemplate>
      <Label>is false</Label>
    </DataTemplate>
  </local:IsWashedStyleSelector.FalseStyle>
</local:IsWashedStyleSelector>

Of course, this is for when you want to use those DataTemplate definitions in only the one place.

The above did not work in my situation where I wanted to change the cell content based on a property bound to the row. I came up with the following solution.

<DataGridTemplateColumn  >
<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <ContentPresenter   
                    Style="{StaticResource LockedStyle}" Content="{Binding}">
        </ContentPresenter>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

With the following styles in the resource dictionary:

  <DataTemplate x:Key="LockedTemplate">
    <TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE72E;" ></TextBlock>
</DataTemplate>
<DataTemplate x:Key="UnLockedTemplate">
    <TextBlock FontFamily="Segoe MDL2 Assets" Text="&#xE785;"></TextBlock>
</DataTemplate>
<DataTemplate x:Key="NoneTemplate"></DataTemplate>
 <Style x:Key="LockedStyle" TargetType="ContentPresenter">
    <Setter Property="ContentTemplate" Value="{StaticResource NoneTemplate}"/>
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsLocked}" Value="true">
            <Setter Property="ContentTemplate" Value="{StaticResource LockedTemplate}"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding IsLocked}" Value="false">
            <Setter Property="ContentTemplate" Value="{StaticResource UnLockedTemplate}"/>
        </DataTrigger>
    </Style.Triggers>
</Style>
         
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top