【问题标题】:INotifyPropertyChanged value not updating value [closed]INotifyPropertyChanged 值不更新值 [关闭]
【发布时间】:2013-06-18 09:42:06
【问题描述】:

我已经挠头 2 天了。虽然我是 .NET 的新手,但我已经阅读了 20 多个帖子和问题,我认为我的代码应该可以工作。有些请投光。

XAML:

<TextBox Grid.Column="3" Name="testgrid" Text="{Binding textsource, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>

后面的代码:

public MainWindow()
{
    InitializeComponent();
    textbind tb = new textbind();
    tb.textsource = "one"; //one is displayed in the textbox.
    testgrid.DataContext = tb;
}

还有:

public class textbind : INotifyPropertyChanged
 {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
          if (PropertyChanged != null)
          {
              PropertyChanged(this, new PropertyChangedEventArgs(info));
          }
        }

    private string a=string.Empty;
    public textbind()
    {

    }


    public string textsource
    {
        get { return a; }
        set
        {
            if (value != a)
            {
                a = value;
                NotifyPropertyChanged(textsource);
            }
        }


         }
}

改变属性:

public class changevalue
{
   //code doing things. this class is initialized by some other processes. 
     textbind tb1 = new textbind();
     tb1.textsource = "two"; // no updates to two in the text box.
}

我相信每次我更改 textsource 属性时,它都会反映文本框中的更改,但它不会发生。索内恩请帮忙。

谢谢。

【问题讨论】:

  • 它不会解决特定问题,但您应该真正将 NotifyPropertyChanged 更改为 var handler = PropertyChanged; if (handler!=null) { handler(this, new PropertyChangedEventArgs(info));} 以帮助避免 PropertyChanged 在测试和执行之间可能变为 null 的线程问题。
  • 我敢打赌,如果您查看“输出”窗口,您会在启动应用程序或更新值时看到绑定错误。这只是 HB 所说的更好的表达方式。

标签: c# .net wpf .net-4.0 inotifypropertychanged


【解决方案1】:
if (value != a)
{
    a = value;
    NotifyPropertyChanged("textsource");
}

您将 textsource 作为变量传递,而 NotifyPropertyChanged 正在提高 textsource 的实际值。相反,您应该传递它的名称“textsource”。

【讨论】:

  • @Naresh:如果你认为这没什么区别,那你根本不知道自己在做什么。
【解决方案2】:

您正在编辑与绑定对象完全不同的对象。

只要你在你的主窗口类中,你就可以这样做

((textbind)testgrid.DataContext).textsource = "two";

如果您不在主窗口类中,则需要确保将放入数据上下文中的 textbind 实例传递给正在执行更新的任何方法。

此外,您需要将 textsource 的实现更改为

public string textsource
{
  get { return a; }
  set
  {
    if (value != a)
    {
      a = value;
      NotifyPropertyChanged("textsource");
    }
  }
}

需要将更改的属性的名称传递给 notifypropertychanged 而不是它的值。

根据 Naresh 的新评论进行更新。

您将需要跟踪实例并在您的代码中传递它,例如在您的更改值类中执行类似的操作

public class changevalue {
 public void doChange(textbind source) {
     source.textsource = "two"; // no updates to two in the text box.
 }
}

然后您需要将 textbind 实例传递给您的 doChange 函数,即如果从 mainform 调用。

或者你可以这样做

public class changevalue {
   public textbind source {get; private set;}

   public changevalue() {
      this.source = new textbind();
   }

   public void doChange() {
     source.textsource = "two"; // no updates to two in the text box.
   }
}

然后,无论您在哪里初始化 changevalue 类,都需要引用您的表单。然后就可以了

var myChangeValue = new changevalue();
mymainform.DataContext = myChangeValue.source;

【讨论】:

  • 是的。我现在知道错误了。
  • 您能否提供更多关于将实例传递给另一个方法的信息?谢谢
  • 啊,我没看到你更新了。虽然我终于得到了我想要的。正如你所说,通过了参考。万分感谢。我花了很多时间才弄明白。
【解决方案3】:

您的视图绑定到textbind 对象的一个​​实例(在您的情况下为tb)。如果您要更改该对象,它将反映在视图中:

tb.textsource = "new value";

但是你正在做的是创建一个新的textbind 对象 (tb1),它没有绑定到视图,期望它在视图更改时修改视图,而事情不是这样工作的。要让它工作,您必须将tb1 设置为您的新DataContext;但是,您真正应该做的只是更改原始绑定对象的textbind 属性。

另外,正如@Nightwish91 所提到的,您的NotifyPropertyChanged 调用应该是这样的

NotifyPropertyChanged("textsource");

否则,视图将收到不正确的属性更改通知,并且不会按预期更新。

【讨论】:

  • 我明白你说的。但那我该怎么做呢?每次改变上下文?我对实施感到震惊。
  • 查看我更新的答案 - 您应该保持相同的 DataContext,但修改原始的 textbind 实例。
  • @Naresh 从 DataContext 中获取 existing 对象并更改它:((textbind)testgrid.DataContext).textsource = "new value";。结合两个答案让事情顺利进行。
猜你喜欢
  • 2011-06-18
  • 1970-01-01
  • 2018-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-17
  • 2012-02-28
  • 1970-01-01
相关资源
最近更新 更多