簡體   English   中英

當依賴的變量或字段發生變化時更新依賴屬性

[英]Update of a Dependency Property when variable or field on which it depends on changes

我需要做的是?

我需要制作一個表達式,依賴屬性應該依賴於哪個。

假設如下:

Count = dependOne + dependTwo;

這里, CountDependency 屬性dependOnedependTwo是依賴屬性Count應該依賴的兩個變量。

現在,每當我更改變量dependOnedependTwo時,依賴屬性都應該自動更新。

可能嗎? 如果是,那怎么辦?

請參閱下面的代碼

XAML:

<Window x:Class="DependecnyProperty.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 Background="LightGray" Text="{Binding Path=Count}" Height="23" HorizontalAlignment="Left" Margin="164,102,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="164,148,0,0" Name="button1" VerticalAlignment="Top" Width="120" Click="button1_Click" />
    </Grid>
</Window>

代碼背后:

namespace DependecnyProperty
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            Count = dependOne + dependTwo;
        }

        int dependOne = 0;
        int dependTwo = 0;

        public int Count
        {
            get { return (int)GetValue(CountProperty); }
            set { SetValue(CountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Count.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CountProperty =
            DependencyProperty.Register("Count", typeof(int), typeof(MainWindow), new UIPropertyMetadata(12));

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            dependOne = dependOne + 2;
            dependTwo = dependTwo + 1;

            //I need to find way ...now here i have changed value of two variable.
            //now it is possible to change Dependency Property
            //Without here setting the value of dependency property
        }


    }
}

編輯更新的代碼隱藏:

namespace DependecnyProperty
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ViewModel vm;
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;

            vm = new ViewModel();
            //this.DataContext = vm;
            Count = vm.DependOne + vm.DependTwo;
        }


        public int Count
        {
            get { return (int)GetValue(CountProperty); }
            set { SetValue(CountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Count.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CountProperty =
            DependencyProperty.Register("Count", typeof(int), typeof(MainWindow), new UIPropertyMetadata(12));

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            vm.DependOne++;
            vm.DependTwo++;
            //I need to find way ...now here i have changed value of two variable.
            //now it is possible to change Dependency Property
            //Without here setting the value of dependency property

        }

        public class ViewModel : INotifyPropertyChanged
        {

            public ViewModel()
            {

            }

            private int dependOne;

            public int DependOne
            {
                get
                {
                    return dependOne;
                }
                set 
                { 
                    dependOne = value;
                    OnPropertyChanged("DependOne");
                }
            }

            private int dependTwo;

            public int DependTwo
            {
                get 
                { 
                    return dependTwo; 
                }
                set 
                { 
                    dependTwo = value;
                    OnPropertyChanged("DependTwo");
                }
            }

            #region --  INotifyPropertyChanged Members  --

            public event PropertyChangedEventHandler PropertyChanged;
            public void OnPropertyChanged(string propertyNameArg)
            {
                PropertyChangedEventHandler handler = this.PropertyChanged;

                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyNameArg));
                }
            }
            #endregion
        }
    }
}

我不知道什么是最適合你的解決方案。 但是,其中之一是您使用以下屬性:

    //field
    private int _dependOne;

    //property
    public int DependOne
    {
        get { return _dependOne; }
        set {
            _dependOne = value;
            Count += value;
        }
    }

    //Finally, use the property instead of the field
    //dependOne = dependOne + 2;
    DependOne += 2;

更新:重要的是您不會在 Codebehind 中更新 ViewModel 屬性。 相反,您可以調用 ViewModel 方法。

XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">

    <StackPanel>
        <StackPanel.Resources>
            <Local:MyConverter x:Key="myConverter"/>
        </StackPanel.Resources>
        <TextBox>
            <TextBox.Text>
                <MultiBinding Converter="{StaticResource myConverter}">
                    <Binding Path="DependOne" Mode="OneWay"/>
                    <Binding Path="DependTwo" Mode="OneWay"/>
                </MultiBinding>
            </TextBox.Text>
        </TextBox>
        <Button Click="button1_Click">click</Button>
    </StackPanel>
</Window>

代碼

public partial class MainWindow : Window
{
    ViewModel vm;
    public MainWindow()
    {
        InitializeComponent();

        vm = new ViewModel();
        this.DataContext = vm;
    }


    //public int Count
    //{
    //    get { return (int)GetValue(CountProperty); }
    //    set { SetValue(CountProperty, value); }
    //}

    //// Using a DependencyProperty as the backing store for Count.  This enables animation, styling, binding, etc...
    //public static readonly DependencyProperty CountProperty =
    //    DependencyProperty.Register("Count", typeof(int), typeof(MainWindow), new UIPropertyMetadata(12));

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        vm.UpdateCount();
    }


}

public class ViewModel : INotifyPropertyChanged
{

    public ViewModel()
    {

    }

    private int dependOne = 0;

    public int DependOne
    {
        get
        {
            return dependOne;
        }
        set
        {
            dependOne = value;
            OnPropertyChanged("DependOne");
        }
    }

    private int dependTwo = 0;

    public int DependTwo
    {
        get
        {
            return dependTwo;
        }
        set
        {
            dependTwo = value;
            OnPropertyChanged("DependTwo");
        }
    }

    #region --  INotifyPropertyChanged Members  --

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyNameArg)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyNameArg));
        }
    }
    #endregion

    internal void UpdateCount()
    {
        DependOne = 3;
        DependTwo = 4;
    }
}

public class MyConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var dependOne = (int)values[0];
        var dependTwo = (int)values[1];

        return (dependOne + dependTwo).ToString();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

ID:

  • dependOnedependTwo放在一個視圖中Model
  • INotifyPropertyChanged添加到視圖 Model
  • 當這些屬性的設置器被調用時引發屬性更改事件
  • 使用MultiBinding將依賴屬性綁定到這兩個視圖 model 屬性

然后,每當這些屬性被更新時,setter 就會自動被調用。

此解決方案的另一個優點是您可以將計數器邏輯與依賴屬性邏輯分開。 單元測試會更容易,並且可能更容易在不同的場景中重用。

Merlyn Morgan-Graham的答案非常相似的方法,您可以在 ViewModel 中引入另一個名為 Count 的只讀屬性。 每當 DependOne 或 DependTwo 更改時引發 PropertyChanged("Count"),然后您可以對 Count 進行 OneWay 綁定

private int m_dependOne;
public int DependOne
{
    get { return m_dependOne; }
    set
    {
        m_dependOne = value;
        OnPropertyChanged("DependOne");
        OnPropertyChanged("Count");
    }
}

private int m_dependTwo;
public int DependTwo
{
    get { return m_dependTwo; }
    set
    {
        m_dependTwo = value;
        OnPropertyChanged("DependTwo");
        OnPropertyChanged("Count");
    }
}

public int Count
{
    get
    {
        return m_dependOne + m_dependTwo;
    }
}

然后綁定就像

<TextBlock Text="{Binding Count, Mode=OneWay}"/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM