Использование DataTrigger для отображения "грязного" значения в DataGridTemplateColumn вместо DataTemplateSelector

У меня все еще есть некоторые проблемы с освоением WPF. Я чувствую, что это, вероятно, простой вопрос, и мне интересно, почему я не могу заставить это работать так, как мне кажется.

Я пытаюсь использовать DataTrigger, чтобы показать, что значение в моей DataGrid является "грязным", что означает, что его значение изменилось с момента последней передачи данных в базу данных. Элементы, связанные с моим видом сетки, имеют свойство IsDirty, которое работает нормально. Я пытаюсь использовать красную звездочку в TextBlock в ячейке сетки, чтобы указать, что есть незафиксированное изменение, используя DataTrigger, как это, в моем DataGrid.Resources. Идея состоит в том, что цвет шрифта изменится с прозрачного на красный, если IsDirty для выбранного элемента строки имеет значение True:

            <DataTemplate x:Key="CleanTemplate">
                <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>

                    <TextBlock Grid.Column="0" Text="*" Padding="0,0,5,0" Foreground="Transparent" FontWeight="Bold" FontFamily="Lucida Console" >
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <!-- Not sure why this isn't working... this text block can't see changes in IsDirty for some reason-->
                                    <DataTrigger Binding="{Binding Path=IsDirty}" Value="True">
                                        <Setter Property="Foreground" Value="Red" />
                                    </DataTrigger>                                                                                                                    
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                    <Label Grid.Column="1" Foreground="DarkGray" Background="Transparent" VerticalContentAlignment="Center" Content="{Binding Path=Value,Mode=OneWay,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
                </Grid>
            </DataTemplate>

Я предполагаю, что DataContext триггера стиля почему-то отличается от DataContext для фактического TextBlock (и метки, которая также является частью ячейки в DataGrid), и мне нужно изменить путь привязки, чтобы триггер мог "видеть" "выбранный элемент и его свойства. Я не уверен, как я могу перейти туда, где он может видеть свойства выбранного элемента в сетке.

Мне удалось заставить его работать с помощью CellTemplateSelector на DataGridTemplateColumn, но клиент запрашивает различные элементы управления вводом в зависимости от типа данных для выбранной строки, поэтому теперь критерии выбора шаблонов данных становятся более сложными (теперь я необходимо иметь шаблон для каждого отдельного элемента управления и один, который в основном совпадает, за исключением отображения значения IsDirty).

XAML:

    <DataGridTemplateColumn
        Header="Value"
        Width="*"
        MinWidth="25"
    >
        <DataGridTemplateColumn.CellTemplateSelector>
            <local:ParameterStateTemplateSelector 
                CleanTemplate="{StaticResource CleanTemplate}"
                CleanTemplateYN="{StaticResource CleanTemplateYN}"
                DirtyTemplate="{StaticResource DirtyTemplate}"
                DirtyTemplateYN="{StaticResource DirtyTemplateYN}"
            />
        </DataGridTemplateColumn.CellTemplateSelector>
    </DataGridTemplateColumn>

Шаблоны для данных типа Label (разница в том, что передний план TextBlock является прозрачным или красным в зависимости от IsDirty):

    <DataTemplate x:Key="CleanTemplate">
        <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Column="0" Text="*" Padding="0,0,5,0" Foreground="Transparent" FontWeight="Bold" FontFamily="Lucida Console" />
            <Label Grid.Column="1" Foreground="DarkGray" Background="Transparent" VerticalContentAlignment="Center" Content="{Binding Path=Value,Mode=OneWay,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="DirtyTemplate">
        <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Column="0" Text="*" Padding="0,0,5,0" Foreground="Red" FontWeight="Bold" FontFamily="Lucida Console"/>
            <Label Grid.Column="1" Foreground="DarkGray" Background="Transparent" VerticalContentAlignment="Center" Content="{Binding Path=Value,Mode=OneWay,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
        </Grid>
    </DataTemplate>

Код для DataTemplateSelector (кажется, что DataTrigger для IsDirty будет проще):

public class ParameterStateTemplateSelector : DataTemplateSelector
{
    public DataTemplate CleanTemplate { get; set; }
    public DataTemplate CleanTemplateYN { get; set; }
    public DataTemplate DirtyTemplate { get; set; }
    public DataTemplate DirtyTemplateYN { get; set; }
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        ScenarioParam selectedItem = (ScenarioParam)item;
            if (selectedItem != null)
        {
            if (selectedItem.ParamObject.DataType == "BOOL")
            {
                if (selectedItem.IsDirty)
                {
                    return DirtyTemplateYN;
                }
                else
                {
                    return CleanTemplateYN;
                }
            }
            else
            {
                if (selectedItem.IsDirty)
                {
                    return DirtyTemplate;
                }
                else
                {
                    return CleanTemplate;
                }
            }
        }
        return base.SelectTemplate(item, container);
    }
}

Любые предложения о том, как я могу заставить DataTrigger "видеть" изменения в свойствах выбранного элемента? Или, возможно, просто невозможно использовать DataTriggers так, как мне бы хотелось?

Спасибо!

0 ответов

Другие вопросы по тегам