【问题标题】:INotifyPropertyChanged does not work when the property set to a same value for the second time当属性第二次设置为相同值时,INotifyPropertyChanged 不起作用
【发布时间】:2011-11-04 05:11:40
【问题描述】:

这是重现此问题的代码:

xaml:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBox Text="{Binding Num,  UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></TextBox>
</Grid>

C#:

using System.ComponentModel;
using System.Windows;

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

public class Entity : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private double num;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public double Num
    {
        get { return num; }
        set
        {
            num = value;
            if (value > 100)
            {
                num = 100;
            }
            OnPropertyChanged("Num");
        }
    }
}

}

现在,如果我运行它,输入 1,就可以了。然后再输入一个1,变成11,还是可以的。 然后再输入一个 1,即 111,现在验证将生效并将值更改为 100,UI 将显示 100。 但是如果我输入更多的数字,用户界面不会改变,它会是 1001。

我猜这与将属性设置为相同的值(100)两次有关。 但我不知道如何修复它,修复它的意思是让 UI 始终遵循属性值。

谢谢

【问题讨论】:

  • 您正在检查值是否 > 100。1001 确实大于 100,因此它正在接受该值,但将私有字段设置为 100。您期望会发生什么?
  • 我不认为你上面的代码准确地代表了你的真实代码;如果它是&gt; 100,上面的设置器only 设置值,并将其设置为100。如果它小于,它永远不会真正设置值。
  • @Chris Shain :我希望 UI 更改为 100,因为即使您输入 1001,属性值也是 100。
  • @Adam Robinson:我刚刚更新了帖子。

标签: c# wpf xaml inotifypropertychanged


【解决方案1】:

在将num 截断为 100 之前引入属性更改通知,并在截断后立即引入一个...

像这样……

        num = value; 
        OnPropertyChanged("Num");
        if (value > 100) 
        { 
            num = 100;
            OnPropertyChanged("Num"); 
        } 

如果有帮助,请告诉我。

【讨论】:

    【解决方案2】:
        <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
       <Window.Resources>
            <!--The Too tip for the textbox-->
            <Style x:Key="txterror" TargetType="{x:Type TextBox}">
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="true">
                        <Setter Property="ToolTip"
                 Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                  Path=(Validation.Errors)[0].ErrorContent}"></Setter>
                        <Setter Property="Background" Value="Red"></Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <Grid>
           <TextBox x:Name="txt" Text="{Binding Mode=TwoWay, IsAsync=True, Path=Num,  UpdateSourceTrigger=PropertyChanged}" Margin="63,36,71,184" >
                <TextBox.Effect>
                    <DropShadowEffect  ShadowDepth="5"/>
                </TextBox.Effect>
            </TextBox>
            <TextBox Margin="63,96,71,124" Text="{Binding ElementName=txt,Path=Text}">
                <TextBox.Effect>
                    <DropShadowEffect ShadowDepth="5" />
                </TextBox.Effect>
            </TextBox>
        </Grid>
    </Window>
    

    使用上面的代码在逻辑上可以正常工作。 意味着当你设置 Num proeprty 的值时,它将 proerty 值设置为 100,但你的窗口的文本框值没有改变。 这是因为它使用错误验证的框架元素,所以无论你想放入文本框的什么,它都会输入并在文本框上显示该值。但是当属性值高于 100 时,属性值始终为 100。

    您的解决方案是在绑定语句中使用 IsAsync=True

    【讨论】:

    • 谢谢,但我已经知道了。现在我需要知道的是如何让 UI 始终遵循属性值。
    • 您的解决方案是在绑定语句中使用 IsAsync=True
    • 呃,你的解决方案是让绑定异步?
    • 谢谢,“IsAsync=True”有帮助。但是现在光标总是在文本框的最左侧,知道如何解决这个问题吗?
    【解决方案3】:

    实际上,只要您在文本框中的输入可以自动转换为双精度,它就应该可以工作。你检查你的输出窗口是否有绑定异常?如果你使用像 1001 这样的值进行调试,你的 setter 会发生什么?

    【讨论】:

    • 不,没有绑定异常。如果我在 setter 中设置断点,会发生的情况是值将设置为 100。
    猜你喜欢
    • 1970-01-01
    • 2011-06-24
    • 2021-12-30
    • 2019-09-30
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    相关资源
    最近更新 更多