【问题标题】:Update XAML TextBlock with value of public property from other class使用其他类的公共属性值更新 XAML TextBlock
【发布时间】:2019-02-03 16:06:52
【问题描述】:

我的 C# WPF 解决方案如下: 带有 startupControl 的主窗口(始终运行) Dialogwindow 与不同的其他控件。 包含一些公共静态属性的公共 Helper 类,以指示客户的哪个部门处于活动状态,以及我目前关注的对象。

我只想在我的 Startupcontrol 中显示两个 XAML 文本块,以便在设置部门或客户的值时显示属性名称。

我认为它可以通过某种绑定正常工作,但我对绑定一无所知,除了它们存在。

是否可以通过对话框窗口中的控件以任何方式更改 Startupcontrol 中 2 个文本块的值?

由于程序很小,而且我确切地知道值何时发生变化,我想我可以创建一个函数来设置值 ex.:

activeDepartmentTextBlock.Text = HelperClass.ActiveDepartment.Name;

但从我在 DialogWindow 中的 control.cs,似乎可以到达 activeDepartmentTextBlock。

谁能帮帮我?

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    从 WPF 4.5 开始,使用属性更改通知绑定到静态属性非常简单。

    下面的示例假设您想要通知 HelperClass 的 ActiveDepartment 属性的更改(而不是关于 Department 对象的 Name 属性的更改)。除了静态属性之外,声明一个名为StaticPropertyChanged 的静态事件并在静态属性更改时触发它:

    public class Department
    {
        public string Name { get; set; }
    }
    
    public class HelperClass
    {
        public static event PropertyChangedEventHandler StaticPropertyChanged;
    
        private static Department activeDepartment;
    
        public static Department ActiveDepartment
        {
            get => activeDepartment;
            set
            {
                activeDepartment = value;
                StaticPropertyChanged?.Invoke(null,
                    new PropertyChangedEventArgs(nameof(ActiveDepartment)));
            }
        }
    }
    

    您可以像这样绑定到静态属性:

    <TextBlock Text="{Binding Path=(local:HelperClass.ActiveDepartment).Name}"/>
    

    【讨论】:

      【解决方案2】:

      Binding 是一个很好的解决方案,但您有静态属性,因此您不能直接使用绑定基础结构来获取更新通知,因为不涉及 DependencyObject(或实现 INotifyPropertyChanged 的对象实例)。

      如果值确实发生了变化,并且您需要在主窗口中更新 TextBlock 的值,您可以创建一个单例而不是静态类来包含该值并绑定到该值。

      单例示例:

      public class HelperClass : DependencyObject {
          public static readonly DependencyProperty ActiveDepartmentProperty =
              DependencyProperty.Register( "ActiveDepartment", typeof( Department ),
              typeof( HelperClass ), new UIPropertyMetadata( "" ) );
          public Department ActiveDepartment {
              get { return (Department) GetValue( ActiveDepartmentProperty ); }
              set { SetValue( ActiveDepartmentProperty, value ); }
          }
      
          public static HelperClass Instance { get; private set; }
      
          static HelperClass() {
              Instance = new HelperClass();
          }
      }
      

      因此绑定将像下面的示例一样工作:

      <TextBox Text="{Binding Source={x:Static local:HelperClass.Instance}, Path=ActiveDepartment.Name}"/>
      

      这可能看起来很难,仅此而已。您可以改用events model 并将事件添加到您的HelperClass。 MainWindow 可以添加事件处理程序并在事件引发时更改 activeDepartmentTextBlock 值。

      public MainWindow()
      {
          InitializeComponent();
          HelperClass.Instance.DepartmentChanged += OnDepartmentChanged;
      }
      
      private void OnDepartmentChanged(Department newDepartment)
      {
          activeDepartmentTextBlock.Text = newDepartment.Name;
      }
      

      更新。如果您想获得最简单的解决方案,您可以打破封装原则并将MainWindow 作为参数传递给DialogWindow 并使activeDepartmentTextBlock 公开。因此,您将能够在DialogWindow 的字段中保存指向MainWindow 的链接,并在需要时更改DialogWindow 中的文本:

      this.mainWindow.activeDepartmentTextBlock.Text = HelperClass.ActiveDepartment.Name;
      

      【讨论】:

      • 不幸的是,目前它看起来有点太复杂了。我希望有一个与用户控件交互的捷径。类似于:this.Usercontrol.ParentControl.ActiveDepartmentTextBlock = Helper.ActiveDepartment.Name;无论如何,感谢您快速而仔细的回答...
      • @Allan 我正在尝试添加另一个简单的解决方案。您的示例将不起作用,因为 dialogWindow 不是主窗口可视树的一部分。
      • “你不能直接使用绑定基础设施来获得通知”是错误的。从 WPF 4.5 开始。有 StaticPropertyChanged 事件,以及静态属性的新绑定路径语法。
      • 好吧,我试过了,但是在我的 XAML 中为 StartupControl 的命名空间有一些问题,所以我暂时离开它,当我有空闲时间时会阅读绑定材料。感谢您迄今为止的帮助!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      • 2020-05-14
      • 1970-01-01
      • 2014-02-12
      • 2018-09-26
      • 1970-01-01
      • 2012-10-29
      相关资源
      最近更新 更多