【问题标题】:DataTrigger not setting properties in pocoDataTrigger 未在 poco 中设置属性
【发布时间】:2015-12-07 12:12:47
【问题描述】:

大家好,我找不到真正能帮助我解决我想做的事情的问题。

我创建了一个DataTemplate 来帮助对我的数据进行一些可视化。

    <DataTemplate x:Key="CsChangeDataDataTemplate" DataType="database:CsChangeData">
        <Grid Width="240">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="48"/>
                <ColumnDefinition Width="192"/>
            </Grid.ColumnDefinitions>
            <Canvas x:Name="icon" Background="{Binding Path=Background, FallbackValue={StaticResource UNK}, TargetNullValue={StaticResource UNK}}" Height="48" Width="48"/>
            <StackPanel Grid.Column="1">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Account" FontWeight="Bold" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5,5,5,2.5" Height="16" Width="64" />
                    <TextBlock Text="{Binding Account, FallbackValue=Unknown, TargetNullValue=Unknown}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="128" Margin="5,5,5,0"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Description" FontWeight="Bold" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5,2.5,5,2.5" Height="16" Width="64"/>
                    <TextBlock x:Name="DescField" Text="{Binding Description, FallbackValue=Unknown, TargetNullValue=Unknown}" HorizontalAlignment="Left" Width="128" VerticalAlignment="Top" Margin="5,2.5,5,0"/>
                </StackPanel>
            </StackPanel>
        </Grid>
        <DataTemplate.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=ChangeType}" Value="None" />
                    <Condition Binding="{Binding Path=Service}" Value="Trunking"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Background" TargetName="icon" Value="{StaticResource TR}"/>
                <Setter Property="Text" TargetName="DescField" Value="Trunking"/>
            </MultiDataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>

我还为它创建了 POCO

    [Serialized]
    public class CsChangeData
    {
        [NonSerialized]
        private DrawingBrush _background;
        public DrawingBrush Background
        {
            get { return _background; }
            set { _background = value; }
        }

        public string Account { get; set; }
        public CsChangeType ChangeType { get; set; }    
        public CsServices Service { get; set; }
        public string Description { get; set; }
        public CsTicket Ticket { get; set; }

        public override string ToString()
        {
            return $"{Description}\r\n" +
                   $"{Ticket.Account}";
        }
    }

这对视觉效果很好,但我只是意识到我正在覆盖DataTemplate 中的绑定集。

我的问题:

如何重写DataTrigger,使其设置CsDataTemplate.Description,而不是直接编辑DescFieldTextProperty

【问题讨论】:

  • 不确定我是否理解正确,但我相信您不能这样做 - DataTrigger 用于设置 XAML 中控件的属性。如果要设置绑定对象的属性,则需要使用 Binding,而不是 DataTrigger。
  • @vesan 这是否意味着我需要使用控件而不是 DataTemplate 来实现这一点?
  • 不,DataTemplate 很好。但是您需要有一些用户可以实际编辑的控件(如 TextBox),并对 ViewModel 的属性进行双向绑定。这提醒我您还应该编写一个视图模型类。如果您不太熟悉,我建议您阅读 MVVM 和 WPF 数据绑定。
  • 谢谢,所有帮助过的人都能得到答案!感谢大家。我会尽力而为。现在虽然我必须将唯一的答案设置为答案 xD

标签: c# wpf data-binding datatrigger multitrigger


【解决方案1】:

你必须做两件事:

  1. 您需要实现 INotifyPropertyChanged 接口,或者通过从 DependencyObject 类继承使您的可绑定对象成为 DependencyObject。

  2. 在您的绑定中,使用&lt;TextBlock Text="{Binding Path=Desc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ... /&gt;

UpdateSourceTrigger 是 DataGrid 所需的罪魁祸首。

【讨论】:

    【解决方案2】:

    您必须将 INotifyPropertyChanged 添加到您的设置器中才能使您的 DataTriggers 工作。您的选择是:

    1) 编写一个 ViewModel 并复制每个字段,并在设置每个字段时发出属性更改通知。

    2) 使用 Castle DynamicProxy 为您的模型创建一个自动执行此操作的包装器。

    3) 使用 Fody,它将在编译时通过后处理步骤将其添加到您的模型类 IL。

    【讨论】:

    • 哈哈,我在没有 MVVM 的情况下这样做,因为我真的无法理解它......我想我需要改变它。感谢您的回答。
    • 好吧,它不一定是 MVVM,但无论哪种方式,DataTriggers 都依赖于数据绑定,因此无论如何都必须添加 INotifyPropertyChanged 支持。
    • 哦,还有一件事你不能像&lt;Condition Binding="{Binding Path=ChangeType}" Value="None" /&gt;那样只传递一个字符串,你必须做像Value="{x:Static local:CsChangeType.None}"这样的事情。
    • 我将属性设置为INotifyPropertyChanged 兼容属性,我还对值和我的所有MultiTriggers 进行了更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多