【问题标题】:WPF invoke method when model property changes模型属性更改时的 WPF 调用方法
【发布时间】:2020-10-19 00:40:14
【问题描述】:

这是我长期面临的问题。
假设我们有一个名为 Person 的 POCO 类(INotifyPropertyChanged 是使用 Foldy 及其 [AddINotifyPropertyChangedInterface] 属性提供的)

[AddINotifyPropertyChangedInterface]
public class Person
{ 
        public int Id{ get; set; }

        [StringLength(20)]
        [Required(ErrorMessage = "Field required")]
        public string FirstName { get; set; }


        [Required(ErrorMessage = "Field required")]
        public string LastName{ get; set; }
}

在 ViewModel 中,我将此类作为属性引用

public class SomeViewModel
{
   public Person Person
   {
      get => person;
      set
      {
          person= value;
          SomeMethod();
      }
   }
// Rest of the code
}

问题是如何在文本框中更改名字时调用“SomeMethod”。
文本框绑定属性如下:

<TextBox Text="{Binding Person.FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged)/>

我试图解决它绑定到:

 public string FirstName
 {
   get => firstName;
   set
      {
        firstName= value;
        Person.FirstName=value;
        SomeMethod();
      }
 }

但问题在于用户表单中的验证,因为我使用 POCO 类中的数据注释属性进行验证。

提前感谢您的帮助和时间!

【问题讨论】:

    标签: c# wpf properties model binding


    【解决方案1】:

    感谢@Thế Long 为我指出了正确的方向,对于那些面临同样问题的人 - 我使用“SourceUpdated”事件以便能够设置绑定延迟 msdn SourceUpdated

    xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity"
    
    <TextBox Text={Binding = " ..., Delay=500"}>
        <i:Interactivity.Triggers>
            <i:EventTrigger EventName="SourceChanged">
                <i:InvokeCommandAction Commmand="{Binding SomeMethodCommand}"/>
            </i:EventTrigger>
        </i:Interactivity.Triggers>
    </TextBox>
    

    【讨论】:

      【解决方案2】:

      你必须听Person的属性变化:

      public class SomeViewModel
      {
        public ViewModel()
        {
          this.Person = new Person();
        }
      
        public Person Person
        {
          get => this.person;
          set
          { 
            if (this.Person != null)
            {
              this.Person.PropertyChanged -= OnPersonFirstNameChanged;
            }
      
            this.person= value;
      
            if (this.Person != null)
            {
              this.Person.PropertyChanged += OnPersonFirstNameChanged;
            }        
          }
        }
      
        public void OnPersonFirstNameChanged(object sender, PropertyChangedEventArgs e)
        {
          if (e.PropertyName == nameof(Person.FirstName))
          {
            SomeMethod();
          }      
        }
      }
      

      或者实现Person 可以引发的Person.FirstNameChanged 事件。这提高了可读性。 PropertyChanged 主要用于数据绑定引擎。由于您必须打开PropertyChangedEventArgs.PropertyChanged 才能了解发生了什么,因此您无法优雅地处理此事件。

      【讨论】:

        【解决方案3】:

        在我看来,有两种选择可以实现您想要的:

        1. 为 Person 创建一个视图模型并将您的方法移动到 FirstName 的设置器。将 Textbox 绑定到 PersonViewModel 的 FirstName 属性,当您更改 TextBox 中的文本时,将调用 SomeMethod()。
        公共类 PersonViewModel
        {
            私有字符串_firstName;
            公共字符串名字
            {
                得到 => _firstName;
                放
                {
                    _firstName = 值;
                    某些方法();
                }
        }
        
        1. 在某些情况下,您必须在所有者 ViewModel 中实现 SomeMethod(),然后只需使用交互性绑定到 Textbox 的 TextChanged 事件并将您的方法分配为调用方法。
        xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity"
        
        <TextBox Name="your_textBox" Text={Binding ...}>
            <i:Interactivity.Triggers>
                <i:EventTrigger EventName="TextChanged">
                    <i:InvokeCommandAction Commmand="{Binding YourMethodInViewModel, ElementName=your_textbox}", CommandParameter="{Binding ElementName=your_textbox}"/>
                </i:EventTrigger>
            </i:Interactivity.Triggers>
        </TextBox>
        
        public ICommand YourMethodInViewModel{get;set;}
        

        【讨论】:

        • 感谢您为我指出正确的方向 - 解决方案是如此接近 :)
        猜你喜欢
        • 2023-03-30
        • 2015-09-27
        • 1970-01-01
        • 2019-02-04
        • 2018-02-04
        • 2018-10-09
        • 1970-01-01
        • 2017-03-21
        • 2013-03-15
        相关资源
        最近更新 更多