【问题标题】:WPF - class property as data triggerWPF - 作为数据触发器的类属性
【发布时间】:2016-11-26 15:17:57
【问题描述】:

我有这段代码,当用户控件中的属性发生更改时,我想在主窗口中更新图像。但不知何故,我无法让触发器工作。

一些 XAML 代码

<StatusBar MinHeight="10" MaxHeight="20" VerticalAlignment="Bottom" Grid.Row="2">
    <Image x:Name="SomeNameHere">
        <Image.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=pingable}" Value="false">
                        <Setter Property="Image.Source" Value="Icons/MainWindow/StatusOffline_stop_32x.png"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=pingable}" Value="true">
                        <Setter Property="Image.Source" Value="Icons/MainWindow/StatusOK_32x.png"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Image.Style>
    </Image>
</StatusBar>

属性来自的部分

public bool pingable { get; set; }

public MainWindow()
{
    InitializeComponent();
    pingable = PingHost("some random IP");
}

public bool PingHost(string nameOrAddress)
{
    pingable = false;
    Ping pinger = new Ping();
    try
    {
        PingReply reply = pinger.Send(nameOrAddress);
        pingable = reply.Status == IPStatus.Success;
    }
    catch (PingException)
    {
        // Discard PingExceptions and return false;
    }
    return pingable;
}

我在 XAML 编辑器中调试期间看到了该属性,因此它似乎可以被识别,并且我还看到该值适合。但不知何故,setter 没有被执行。 有人对此有想法吗?

谢谢,祝你有美好的一天!

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    您需要在pingable 上引发您的PropertyChanged 事件以更新视图。

    基本上,为了让视图知道它需要基于绑定更新某些控件,您的视图模型需要实现INotifyPropertyChanged;任何时候你想根据视图模型的变化来更新视图,你需要从视图模型中引发 PropertyChanged 并将其值已更新的绑定属性的名称传递给它。

    【讨论】:

    • 谢谢你。这实际上对我帮助很大。稍后会回复我的处理方式。
    【解决方案2】:

    如果您在 getter 和 setter 上 RaisePropertyChanged,它将在属性更改时通知 XAML 并触发触发器。 试试这个代码:

     bool _pingable;
     public bool pingable 
     {
        get{return _pingable;} 
        set{ _pingable = value; RaisePropertyChanged;}
     };
    

    【讨论】:

      【解决方案3】:

      虽然我之前的其他两个答案指出需要实现INotifyPropertyChanged——这对于普通的 WPF 应用程序来说有些重要——但我认为这在这里并不重要。您的 ping 请求看起来是同步的,因此在您更新值时实际上不会加载 UI,这使得 INotifyPropertyChanged 无关紧要。

      public partial class MainWindow : Window
      {
          public MainWindow()
          {
              InitializeComponent();
              DataContext = this;
              Thread.Sleep(2000);  // pretending to ping
              Flag = true;
          }
      
          public bool Flag { get; set; }
      }
      

      XAML:

      <Grid>
          <CheckBox IsChecked="{Binding Flag}" />
      </Grid>
      

      当窗口最终加载时会检查此项。如果这是异步的,那就另当别论了。

      我在 XAML 编辑器中调试期间看到了该属性

      我不确定这意味着什么。我怀疑这里的实际问题是您没有定义 DataContext 。 (也许是,但我在这里看不到!)

      您已经在窗口本身上创建了属性,所以...如果您将触发器切换为...

      <DataTrigger Binding="{Binding Path=pingable, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" Value="false">
      

      【讨论】:

        猜你喜欢
        • 2013-02-16
        • 2011-07-06
        • 1970-01-01
        • 2011-02-24
        • 1970-01-01
        • 1970-01-01
        • 2016-01-13
        • 1970-01-01
        • 2011-09-06
        相关资源
        最近更新 更多