WPF多重绑定文本块未更新

时间:2010-05-12 17:39:24

标签: c# binding

我想创建一个程序来计算重复某个过程需要多长时间。我已经为这个例子缩减了很多。

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

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属性更新多重文本块,但Days属性始终显示为0,即使Days输入准确反映了更改。我相信这是因为我的访问者对于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 个答案:

答案 0 :(得分:1)

首先TimeSpan是一个不可变的结构,所以你需要存储任何操作的结果,否则它实际上是一个无操作。此外,您需要致电OnPropertyChanged,同时更改SpanDays

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));
    }
}