1

What is the proper way, for the UI to get notified, that property "Difference" has changed in the following code sample?

The property is read-only. The property's value must always be calculated based on the other properties.

MainWindow.xaml:

<Window x:Name="winCalcs" x:Class="BindingList.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:m="clr-namespace:BindingList"
        Title="Calculations" Height="350" Width="525">
    <Window.Resources>
        <m:OperationList x:Key="OperationData"/>
        <CollectionViewSource x:Key="Operations" 
                              Source="{StaticResource ResourceKey=OperationData}"/>
    </Window.Resources>

    <Grid>
        <TabControl x:Name="tabsMain">
            <TabItem x:Name="tab01" Header="Tab 1">
                <DataGrid x:Name="dg01"
                          ItemsSource="{Binding 
                    Source={StaticResource ResourceKey=Operations}, 
                    UpdateSourceTrigger=PropertyChanged}" />
            </TabItem>
            <TabItem x:Name="tab02" Header="Tab 2">
                <DataGrid x:Name="dg02" 
                          ItemsSource="{Binding 
                    Source={StaticResource ResourceKey=Operations}, 
                    UpdateSourceTrigger=PropertyChanged}" />
            </TabItem>
        </TabControl>
    </Grid>

</Window>

Operation.cs:

namespace BindingList
{
    class Operation : INotifyPropertyChanged 
    {
        private float _minuend;

        private float _subtrahend;

        public float Minuend
        {
            get
            {
                return this._minuend;
            }
            set
            {
                if (this._minuend == value) return;
                this._minuend = value;
                this.NotifyPropertyChanged("Minuend");
            }
        }

        public float Subtrahend
        {
            get
            {
                return this._subtrahend;
            }
            set
            {
                if (this._subtrahend == value) return;
                this._subtrahend = value;
                this.NotifyPropertyChanged("Subtrahend");
            }
        }

        public float Difference 
        {
            get
            {
                return Minuend - Subtrahend;
            }
            private set {}
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

OperationList.cs:

namespace BindingList
{
    class OperationList : BindingList<Operation>
    {
        public OperationList()
        {
            Add(new Operation());
        }
    }
}
4

2 回答 2

3

Difference changes when Minuend or Subtrahend changes. That means you need to notify changed for Difference within the set of Minuend or Subtrahend.

There is no need for property setter for Difference.

On a side note, there is no need for using this everywhere

public float Minuend
{
    get
    {
        return _minuend;
    }
    set
    {
        if (_minuend == value) return;
        _minuend = value;
        NotifyPropertyChanged("Minuend");
        NotifyPropertyChanged("Difference");
    }
}

public float Subtrahend
{
    get
    {
        return _subtrahend;
    }
    set
    {
        if (_subtrahend == value) return;
        _subtrahend = value;
        NotifyPropertyChanged("Subtrahend");
        NotifyPropertyChanged("Difference");
    }
}

public float Difference 
{
    get
    {
        return Minuend - Subtrahend;
    }
}
于 2015-04-16T11:31:05.340 回答
0

In these situations I typically set the property explicitly and and raise the PropertyChanged event.

namespace BindingList
{
    class Operation : INotifyPropertyChanged
    {
        private float _minuend;
        private float _subtrahend;
        private float _difference;
        public float Minuend
        {
            get
            {
                return this._minuend;
            }

            set
            {
                if (this._minuend == value)
                    return;
                this._minuend = value;
                this.NotifyPropertyChanged("Minuend");
                this.UpdateDifference();
            }
        }

        public float Subtrahend
        {
            get
            {
                return this._subtrahend;
            }

            set
            {
                if (this._subtrahend == value)
                    return;
                this._subtrahend = value;
                this.NotifyPropertyChanged("Subtrahend");
                this.UpdateDifference();
            }
        }

        private void UpdateDifference()
        {
            this.Difference = this.Minuend - this.Subtrahend;
        }

        public float Difference
        {
            get
            {
                return this._difference
            }

            private set
            {
                if (this._difference == value)
                    return;
                this._difference = value;
                this.NotifyPropertyChanged("Difference");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string p)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(p));
        }
    }
}
于 2015-04-16T11:32:59.573 回答