首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >结合PropertyChanged引理

结合PropertyChanged引理
EN

Stack Overflow用户
提问于 2014-02-10 07:56:51
回答 4查看 131关注 0票数 0

哦,主啊,又是星期一了,我觉得我所有关于wpf的知识都被删除了。

我认为在模式PropertyChanged中绑定时,源将只在目标属性被更改时才会更新,而不是一直更新。

下面是一个例子,在这个例子中,尽管Target属性没有被更改,绑定仍然在不断地更新Source。为什么?

顺便说一句,我在.NET 4.0

代码语言:javascript
复制
  <StackPanel>
    <TextBox x:Name="tbx1" Text="{Binding Txt, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <Button Content="Change Text" Click="OnClick" />
  </StackPanel>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }

    private void OnClick(object sender, RoutedEventArgs e)
    {
        tbx1.Text = "hello";
    }
}

public class ViewModel 
{

    private string txt;

    public string Txt
    {
        get { return txt; }
        set { txt = value; Console.WriteLine("Txt Setter Called!");}
    }
}

每当我点击Button,Txt的设置程序就会被调用。为什么?值未被更改。

GetHashCode()方法返回相同的结果。

我少了什么??:-)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-10 17:47:52

正如您所预期的,没有发生实际的“属性更改”,可以通过以下方法确认:

代码语言:javascript
复制
using System.ComponentModel;

var descriptor = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));

descriptor.AddValueChanged(tbx1, (s, e) => Console.WriteLine("tbx1 changed"));

“已更改的tbx1”只出现一次。

如果源是一个依赖项属性,那么它也不会改变。尝试添加另一个文本框并将其用作源代码,而不是视图模型:

代码语言:javascript
复制
<TextBox Name="tbx2" />
<TextBox Name="tbx1" Text="{Binding ElementName=tbx2, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

处理程序:

代码语言:javascript
复制
descriptor.AddValueChanged(tbx2, (s, e) => Console.WriteLine("tbx2 changed"));

再说一次,只有一次改变。

所以是的,扳机没有准确的命名。此行为的一个原因可能是确保属性集总是触发绑定转换器,因为即使输入相同,ConvertBack也可以返回不同的值。

无论如何,目标和源都需要承担一定的责任来确定“更改”是什么。毕竟,如果这是一个真正的双向绑定,那么应该允许我们以完全相同的效果以这种方式实现OnClick

代码语言:javascript
复制
tbx1.DataContext.Txt = "hello";

因此,只需确保属性设置者在继续之前始终检查实际更改(就像依赖项属性一样)。

票数 1
EN

Stack Overflow用户

发布于 2014-02-10 09:58:30

好吧,这就是它的工作方式,但这个名字可能有点误导。

在设置目标属性时更新源值,而不一定是在值更改时(如名称所示)。

您可以通过使用fx观察相同的行为。一个CheckBox。一次又一次地将IsChecked属性设置为true也会触发源更新,即使目标值没有变化。

因此,绑定系统在触发更新之前不对实际值进行比较,它只关心目标属性是否已设置。

CheckBox扩展了您的示例

XAML:

代码语言:javascript
复制
<StackPanel>
    <TextBox x:Name="tbx1" Text="{Binding Txt, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <CheckBox x:Name="chk1" IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    <Button Content="Change Text" Click="OnClick" />
</StackPanel>

代码隐藏:

代码语言:javascript
复制
public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }

    private void OnClick(object sender, RoutedEventArgs e)
    {
        tbx1.Text = "hello";
        chk1.IsChecked = true;
    }
}

public class ViewModel
{
    private string txt;
    public string Txt
    {
        get { return txt; }
        set { txt = value; Console.WriteLine("Txt Setter Called!"); }
    }

    private bool isChecked;
    public bool IsChecked
    {
        get { return isChecked; }
        set { isChecked = value; Console.WriteLine("IsChecked Setter Called!"); }
    }
}
票数 2
EN

Stack Overflow用户

发布于 2014-02-10 07:59:56

BindingMode更改为OneWayOneWayToSource。你的问题会解决的..。

代码语言:javascript
复制
<TextBox x:Name="tbx1" Text="{Binding Txt, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"/>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21671727

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档