What I need to do is?
I need to make one expression on which dependency property should depends on.
Suppose as per below:
Count = dependOne + dependTwo;
Here, Count
is Dependency property and dependOne
and dependTwo
are two variables on which dependency property Count
should Depends on.
Now whenever I change variable dependOne
or dependTwo
the dependency property should have to update automatically.
Is it possible? If yes then how?
See the code below
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>
CODE BEHIND:
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 UPDATED 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
}
}
}
I don't know what is the best solution for you. One of these ,however, would be that you use Property like:
//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;
UPDATED: The important thing is that you don't update ViewModel properties in Codebehind. Instead, you could call a ViewModel method.
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();
}
}
I'd:
- Put
dependOne
anddependTwo
in a View Model - Add
INotifyPropertyChanged
to the View Model - Raise the property changed event when those property's setters got called
- Use a MultiBinding to bind the dependency property to those two view model properties
Then the setter would automatically get called whenever those properties were updated.
Another advantage of this solution is that you could separate the counter logic from the dependency property logic. It would be easier to unit test, and possibly easier to reuse in different scenarios.
A pretty similar approach to the answer by Merlyn Morgan-Graham, you can introduce another readonly property called Count in your ViewModel. Raise PropertyChanged("Count") whenever DependOne or DependTwo changes, then you can do a OneWay binding against Count
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;
}
}
Then binding is just as simple as
<TextBlock Text="{Binding Count, Mode=OneWay}"/>
精彩评论