简体   繁体   English

WPF:如何手动更新DataTrigger

[英]WPF: How to update DataTrigger manually

Trigger doesn't update when using attached property. 使用附加属性时,触发器不会更新。

Window1.xaml Window1.xaml

<Window x:Class="proj1.Window1"
        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:proj1"
        mc:Ignorable="d"
        Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="ListView" x:Key="style1">
            <Setter Property="View">
                <Setter.Value>
                    <GridView>
                        <GridViewColumn Header="1" DisplayMemberBinding="{Binding one}" Width="100" />
                        <GridViewColumn Header="2" DisplayMemberBinding="{Binding two}" Width="100" />
                    </GridView>
                </Setter.Value>
            </Setter>
            <EventSetter Event="GridViewColumnHeader.Click" Handler="ColumnHeader_Click"/>
            <Style.Triggers>
                <!--
                <Trigger Property="Column.local:TestClass.Flag" Value="True">
                    <Setter Property="Foreground" Value="Red" />
                </Trigger>
                -->
            </Style.Triggers>
        </Style>
        <Style TargetType="ListView" x:Key="style2">
            <Setter Property="View">
                <Setter.Value>
                    <GridView>
                        <GridViewColumn Header="1" DisplayMemberBinding="{Binding one}" Width="100" />
                        <GridViewColumn Header="2" DisplayMemberBinding="{Binding two}" Width="100" />
                    </GridView>
                </Setter.Value>
            </Setter>
            <EventSetter Event="GridViewColumnHeader.Click" Handler="ColumnHeader_Click"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Column, RelativeSource={RelativeSource Self}, Converter={x:Static local:TestClass.Converter}}" Value="True">
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <ListView Grid.Row="0" Style="{StaticResource style1}" ItemsSource="{Binding items}" />
        <ListView Grid.Row="1" Style="{StaticResource style2}" ItemsSource="{Binding items}" />

    </Grid>
</Window>

Window1.xaml.cs Window1.xaml.cs

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace proj1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            // set dummy data
            this.DataContext = new
            {
                items = new[]
                {
                    new {
                        one = "A",
                        two = "a",
                    },
                    new {
                        one = "B",
                        two = "b",
                    },
                    new {
                        one = "C",
                        two = "c",
                    },
                    new {
                        one = "D",
                        two = "d",
                    },
                }
            };
        }

        /// <summary>
        /// cannot change!
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ColumnHeader_Click(object sender, RoutedEventArgs e)
        {
            var column_header = e.OriginalSource as GridViewColumnHeader;

            if (column_header == null) return;

            var column = column_header.Column;

            if (column == null) return;

            TestClass.Setflag(column, !TestClass.GetFlag(column));

            // debug print
            Console.WriteLine($"{column_header.Content} / {TestClass.GetFlag(column)}");
        }
    }

    /// <summary>
    /// Define 'Flag' AttachedProprety and IValueCoverter which pick
    /// 'Flag' AttachedProperty from a DependencyObject
    /// </summary>
    public class TestClass
    {
        public static bool GetFlag(DependencyObject obj)
        {
            return (bool)obj.GetValue(FlagProperty);
        }

        public static void Setflag(DependencyObject obj, bool value)
        {
            obj.SetValue(FlagProperty, value);
        }

        // Using a DependencyProperty as the backing store for flag.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FlagProperty =
            DependencyProperty.RegisterAttached("Flag", typeof(bool), typeof(TestClass), new PropertyMetadata(false));

        public static IValueConverter Converter => new GetFlagConverter();

        public class GetFlagConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                var dobj = value as DependencyObject;
                if (dobj == null)
                {
                    return false;
                }

                return GetFlag(dobj);
            }

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }
}

At first, I tried "style1" code. 首先,我尝试了“ style1”代码。 But, "Column.local:TestClass.Flag" has an error. 但是,“ Column.local:TestClass.Flag”有错误。

So, I tried "style2" code. 因此,我尝试了“ style2”代码。 It has no errors. 没有错误。

But, font color didn't change. 但是,字体颜色没有改变。

How can I update DataTrigger manually? 如何手动更新DataTrigger

there is a problem between your triggers target and the object you set the trigger to (in style 1). 在触发器目标和您将触发器设置为的对象之间(在样式1中)存在问题。 To color the headers text you need to change the following: 要为标题文本着色,您需要更改以下内容:

    <Style x:Key="style1" TargetType="ListView">
    <Setter Property="View">
        <Setter.Value>
            <GridView>
                <GridViewColumn Width="100"
                                DisplayMemberBinding="{Binding one}"
                                Header="1">
                    <GridViewColumn.HeaderContainerStyle>
                        <Style TargetType="GridViewColumnHeader">
                            <Style.Triggers>
                                <Trigger Property="local:TestClass.Flag" Value="True">
                                    <Setter Property="Foreground" Value="Red" />
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </GridViewColumn.HeaderContainerStyle>
                </GridViewColumn>
                <GridViewColumn Width="100"
                                DisplayMemberBinding="{Binding two}"
                                Header="2" >
                    <GridViewColumn.HeaderContainerStyle>
                        <Style TargetType="GridViewColumnHeader">
                            <Style.Triggers>
                                <Trigger Property="local:TestClass.Flag" Value="True">
                                    <Setter Property="Foreground" Value="Red" />
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </GridViewColumn.HeaderContainerStyle>
                </GridViewColumn>
            </GridView>
        </Setter.Value>
    </Setter>
    <EventSetter Event="GridViewColumnHeader.Click" Handler="ColumnHeader_Click" />
</Style>

and

private void ColumnHeader_Click(object sender, RoutedEventArgs e)
{
    var column_header = e.OriginalSource as GridViewColumnHeader;

    if (column_header == null) return;

    TestClass.Setflag(column_header, !TestClass.GetFlag(column_header));
}

this sets the Flag for your ColumnHeader element. 这将为您的ColumnHeader元素设置Flag The Style.Trigger now is at your ColumnHeader and will been performed correctly. Style.Trigger现在在您ColumnHeader ,将被正确执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM