代码之家  ›  专栏  ›  技术社区  ›  user164226

WPF多绑定文本块未更新

  •  1
  • user164226  · 技术社区  · 16 年前

    因此,我有一些文本框绑定到类中的属性:

    Count: <TextBox x:Name="txtCount" Text="{Binding Count, Mode=TwoWay}" Width="50"/>
    Days: <TextBox x:Name="txtDays" Text="{Binding Days, Mode=TwoWay}" Width="50"/>
    

    以及一个文本块,它是这样的多重绑定:

    <TextBlock x:Name="tbkTotal">
        <TextBlock.Text>
            <MultiBinding StringFormat="Days: {0}, Count: {1}">
                <Binding Path="Days" /> /* This isn't updating */
                <Binding Path="Count" />
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>
    

    我的DataContext在Window1.xaml.cs文件中设置。

    public Window1()
            {
                InitializeComponent();
                Sample sample = new Sample();
                this.DataContext = sample;
            }
    

    我可以用Count属性更新multiboundtextblock,但是Days属性总是显示0,即使Days输入准确地反映了更改。我相信这是因为我的访问器在几天内是不同的,即Set方法。此类位于不同的文件中。

    public class Sample : INotifyPropertyChanged
        {
            private int _count;
            private TimeSpan _span;
    
            public int Count 
            { 
                get { return _count; } 
                set 
                { 
                    _count = value;
                    NotifyPropertyChanged("Count"); /* Doesn't seem to be needed, actually */
                } 
            }
    
            public TimeSpan Span { get { return _span; } }
    
    /* The idea is to provide a property for Days, Hours, Minutes, etc. as conveniences to the inputter */
    
            public double Days
            {
                get { return _span.Days; }
                set
                {
                    TimeSpan ts = new TimeSpan();
                    double val = value > 0 ? value : 0;
                    ts = TimeSpan.FromDays(val);
                    _span.Add(ts); /* !! This turned out to be the problem, lol - see SixLetterVariables' answer below. */
                    NotifyPropertyChanged("Span"); /* Here I can only get it to work if I notify that Span has changed - doesn't seem to be aware that the value behind Days has changed. */
                }
            }
    
            private void NotifyPropertyChanged(string property)
            {
                if (null != this.PropertyChanged)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(property));
                }
            }
            public Sample()
            {
                _count = 0;
                _span = new TimeSpan();
            }
            public event PropertyChangedEventHandler PropertyChanged;
        }
    
    1 回复  |  直到 16 年前
        1
  •  1
  •   user7116    16 年前

    首先 TimeSpan 是一个不可变的结构,因此您需要存储任何操作的结果,否则它实际上是一个不操作 OnPropertyChanged Span 和 Days

    public double Days
    {
        get { return _span.Days; }
        set
        {
            double val = value > 0 ? value : 0;
    
            // TimeSpan is an immutable struct, must store the result of any
            // operations on it
            _span = TimeSpan.FromDays(val);
    
            this.OnPropertyChanged("Days");
            this.OnPropertyChanged("Span");
        }
    }
    
    // This is preferred way for handling property changes
    private event PropertyChangedEventHandler propertyChanged;
    public event PropertyChangedEventHandler PropertyChanged
    {
        add { this.propertyChanged += value; }
        remove { this.propertyChanged -= value; }
    }
    
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = this.propertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
    推荐文章