【问题标题】:Setting the tag property of a button to an integer value and firing a trigger将按钮的 tag 属性设置为整数值并触发触发器
【发布时间】:2011-09-16 13:21:31
【问题描述】:

我想做以下类似的事情,但它不起作用。我想使用数据触发器将整数(或任何类型)值设置为我在数据模板中定义的按钮的标记属性。然后在按钮的图像样式内部,当相应的值设置为按钮的标记属性时触发触发器。但它似乎并没有以这种方式工作。如果我设置了 x:Null 值,我可以触发触发器,这意味着逻辑正常。但是设置像 0 或 1 这样的值不会触发触发器。有什么解决办法吗?

<DataTemplate x:Key="SomeDataTemplateofSomeType">

<Button x:Name="ButtonVisible">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Image x:Name="FxImage">
                  <Image.Style>
                      <Style TargetType="{x:Type Image}">
                        <Style.Triggers>
                           <DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource TemplatedParent},UpdateSourceTrigger=PropertyChanged}" Value="0">
                               <Setter Property="Source" Value="/Resources/controls/images/fxiconsnone.png" />
                           </DataTrigger>
                        </Style.Triggers>
                      </Style>
                 </Image.Style>
            </Image>
        </ControlTemplate>
   </Button.Template>
</Button>

<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsVisible, Value="True">
    <Setter Property="Tag" TargetName="ButtonVisible" Value="1" />
</DataTrigger>

<DataTrigger Binding="{Binding Path=IsVisible, Value="False">
    <Setter Property="Tag" TargetName="ButtonVisible" Value="0" />
</DataTrigger>
</DataTemplate.Triggers>
</Datatemplate>

【问题讨论】:

    标签: wpf xaml datatemplate datatrigger setter


    【解决方案1】:

    您绑定到ImageDataContext,而不是模板化的Button

    改为绑定到TemplatedParent

    附带说明,没有必要使用两个DataTriggers 来表示真假。改为这样做

    <Button x:Name="ButtonVisible" Tag="1">
    

    并且只保留DataTriggers之一

    <DataTrigger Binding="{Binding Path=IsVisible}" Value="False">
        <Setter Property="Tag" TargetName="ButtonVisible" Value="0" />
    </DataTrigger>
    

    示例,将以下内容添加到MainWindow.xaml

    <StackPanel>
        <StackPanel.Resources>
            <DataTemplate x:Key="SomeDataTemplateofSomeType">
                <Button x:Name="ButtonVisible">
                    <Button.Template>
                        <ControlTemplate TargetType="Button">
                            <Image x:Name="FxImage">
                                <Image.Style>
                                    <Style TargetType="{x:Type Image}">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource TemplatedParent},UpdateSourceTrigger=PropertyChanged}" Value="0">
                                                <Setter Property="Source" Value="YourImageSource" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Image.Style>
                            </Image>
                        </ControlTemplate>
                    </Button.Template>
                </Button>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Path=IsVisible}" Value="True">
                        <Setter Property="Tag" TargetName="ButtonVisible" Value="1" />
                    </DataTrigger> 
                    <DataTrigger Binding="{Binding Path=IsVisible}" Value="False">
                        <Setter Property="Tag" TargetName="ButtonVisible" Value="0" />
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </StackPanel.Resources>
        <ContentControl Content="{Binding MySource}"
                        ContentTemplate="{StaticResource SomeDataTemplateofSomeType}"/>
        <ToggleButton IsChecked="{Binding Path=MySource.IsVisible, Mode=TwoWay}" Content="IsChecked?"/>
    </StackPanel>
    

    MainWindow.xaml.cs

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MySource = new MySource();
    
            this.DataContext = this;
        }
        public MySource MySource
        {
            get;
            set;
        }
    }
    public class MySource : INotifyPropertyChanged
    {
        private bool m_isVisible;
        public bool IsVisible
        {
            get { return m_isVisible; }
            set
            {
                m_isVisible = value;
                OnPropertyChanged("IsVisible");
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    【讨论】:

    • 对不起,我从我的复制粘贴中错过了这段代码。我的代码已经是这样了,我将编辑第一篇文章以避免任何误解。虽然这样还是不行,所以你知道我该怎么做吗? :(
    • @muku:嗯,我将您的代码复制到我自己的测试项目中,并且它工作正常,所以一定是其他问题。我会检查你的更新
    • 你确定吗?因为正如我告诉你的,如果我的设置器将值设置为 {x:Null} 触发器会正确触发。如果我将设置器值更改为 0 或 1,则不会触发触发器。而且在 setter 内部我设置了另一个值,一个文本块文本,用于知道 setter 被首先触发并被触发......
    • 是的,我当然确定 :) 否则我不会这么说.. 我会添加一个例子
    • 好的,我很感激,我正在等待:)
    猜你喜欢
    • 2012-11-23
    • 2016-12-16
    • 2013-08-30
    • 2012-10-15
    • 2014-11-04
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 2013-04-09
    相关资源
    最近更新 更多