2011-07-16 317 views
1

我需要做的是?依賴於變量的變量或字段時依賴項屬性的更新

我需要做一個表達式上依賴屬性應該依賴。

假設按如下:

Count = dependOne + dependTwo; 

這裏,Count依賴屬性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 
     } 
    } 
} 

回答

3

我不知道什麼是最適合您的解決方案。其中的一個,但是,這是你使用類似物業:

//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; 

更新: 重要的是,你不更新代碼隱藏視圖模型屬性。相反,你可以調用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> 

CODE

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(); 
    } 
} 
+0

雅這其中也使得SENCE .. ... –

+0

是的,這是一個簡單的...因爲不知道你的實際情況,我只是這麼說,但我認爲@Merlyn Morgan-Graham是一個好點。另外,如果dependOne作用於View,則可以考慮將dependOne作爲「DependecnyProperty」。然後,使用「Value Changed Callback」更新計數。 –

+0

謝謝你回答..但..,根據格雷厄姆的答案.....我們必須把表達式...'計數= dependOne + dependTwo; ' –

3

我倒是:

  • dependOnedependTwo在視圖模型
  • 添加INotifyPropertyChanged向視圖模型
  • 提高時,這些屬性的制定者接到電話
  • 使用MultiBinding的依賴屬性

然後二傳手綁定到這兩個視圖模型的屬性會自動將屬性更改事件每當這些屬性被更新時都會被調用。

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

+0

好吧..我正在嘗試....感謝回答.... –

+0

@格拉姆姆,,,我很困惑把'表達式'..... .....'計數= dependOne + dependTwo;' –

+0

@Aryan:你可以把它放在一個自定義的'IMultiValueConverter'中,與'MultiBinding'一起使用。 –

2

一個非常相似的方法來回答Merlyn Morgan-Graham,您可以在ViewModel中引入另一個名爲Count的只讀屬性。提高的PropertyChanged(「計數」),每當DependOne或DependTwo變化,那麼你可以做一個單向對伯爵結合

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}"/>