2011-07-16 1 views
1

Что мне нужно сделать?Обновление зависимого свойства при изменении или поле, от которого оно зависит от изменений

Мне нужно сделать одно выражение, от которого должно зависеть свойство зависимостей.

Пусть согласно ниже:

Count = dependOne + dependTwo; 

Здесь Count является Dependency свойство и dependOne и dependTwo две переменные, на которых свойства зависимостей Count должны Зависит.

Теперь, когда я изменяю переменную dependOne или dependTwo, свойство зависимостей должно обновляться автоматически.

Возможно ли это? Если да, то как?

Смотрите ниже код

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 
     } 


    } 
} 

EDIT ОБНОВЛЕНО CodeBehind:

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 в CodeBehind. Вместо этого вы можете вызвать метод 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(); 
    } 
} 
+0

я это один и делает Sence .. .... –

+0

Да, это просто ... Как не зная вашей реальной ситуации, я просто сказал это, но я думаю, что @Merlyn Morgan-Graham - хороший момент. Кроме того, вы можете подумать о том, чтобы сделать dependOne «DependecnyProperty», если функция dependOne действует на View. Затем используйте «Value Changed Callback» для обновления Count. –

+0

Спасибо, что ответили .. но .. ,, согласно ответу Грэма ..... где мы должны положить выражение ... 'Count = dependOne + dependTwo; ' –

3

Я бы:

  • Помещенный dependOne и dependTwo в виде модели
  • Добавить INotifyPropertyChanged в Модельные
  • Поднять свойство измененного событие, когда сеттера тех, где предлагаются получили под названием
  • Используйте MultiBinding связать свойство зависимостей к свойствам модели два просмотреть

Тогда сеттерами будет автоматически вызывается при каждом обновлении свойств.

Другим преимуществом этого решения является то, что вы можете отделить логику счетчика от логики свойств зависимостей. Было бы проще провести единичный тест и, возможно, проще повторное использование в разных сценариях.

+0

Хорошо .. я пытаюсь .... спасибо за ответ .... –

+0

@Graham ,,, я смущен, куда положить 'Expression' .....' Count = dependOne + dependTwo; ' –

+0

@Aryan: Вы поместили бы его в пользовательский 'IMultiValueConverter', который будет использоваться с' MultiBinding'. –

2

Довольно похожий подход к ответу Merlyn Morgan-Graham, вы можете ввести другое свойство readonly под названием Count в вашей модели ViewModel. Поднять PropertyChanged ("Count") всякий раз, когда изменяется DependOne или DependTwo, то вы можете сделать 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}"/> 
Смежные вопросы