I'm trying to figure out how to properly pass properties through multiple classes. I know I can just implement INotifyPropertyChanged
in each class and listen for changes on the property, but this seems to be quite a lot of unnecessary code.
The situation:
I have a class (let's call it Class1
) with two dependency properties: FilterStatement
(String) and Filter
(Filter class). Setting the statement affects the filter and vice versa.
The conversion logic between statement and filter, however, isn't located in Class1
, but in Class3
- which Class1
doesn't know directly. In between there is Class2
which just has to pass through the changes. (You can imagine class 1 to 3 beeing Viewmodel, Model and Repository, though in the real situation this doesn't completly match).
public class Class1
{
public static readonly DependencyProperty FilterProperty = DependencyProperty.Register(
"Filter",
typeof(Filter),
typeof(Class1),
new FrameworkPropertyMetadata(null));
public static readonly DependencyProperty FilterStatementProperty = DependencyProperty.Register(
"FilterStatement",
typeof(String),
typeof(Class1),
new FrameworkPropertyMetadata(null));
public Filter Filter
{
get { return (Filter)GetValue(FilterProperty); }
set { SetValue(FilterProperty, value); }
}
public string FilterStatement
{
get { return (string)GetValue(FilterStatementProperty); }
set { SetValue(FilterStatementProperty, value); }
}
public Class2 MyClass2Instance { get; set; }
}
public class Class2
{
public Class3 MyClass3Instance { get; set; }
public void ChangeClass3Instance(object someParam) {
... // this can change the instance of MyClass3Instance and is called frome somewhere else
// when changed, the new Class3 instance has to get the property values of Class1
}
}
public class Class3
{
private Filter _filter; // here is where the filter set in Class 1 or determined by the statement set in class 1 has to be put
public string MyFilterToStatementConversionMemberFunction(Filter filter)
{
...
}
public Filter MyStatementToFilterConversionMemberFunction(string statement)
{
...
}
}
My naive solution would be to duplicate the properties across all three classes, implement INotifyPropertyChanged
in Class2
and Class3
and listen to the changes, propagating everything down to Class3
and in Result back up to Class1
. Isn't there a better solution to this?
Actually, while Class1
is not a control (given it is a ViewModel) I don't see a reason to make its properties as DependencyProperty
, because implementation of INotifyPropertyChanged
should be enough.
However, implementation with DependencyProperty
should work as well:
public class Class1
{
public static readonly DependencyProperty FilterProperty =
DependencyProperty.Register(
nameof(Filter),
typeof(Filter),
typeof(Class1),
new PropertyMetadata(OnPropertyChanged));
public static readonly DependencyProperty FilterStatementProperty =
DependencyProperty.Register(
nameof(FilterStatement),
typeof(string),
typeof(Class1),
new PropertyMetadata(OnPropertyChanged));
public Filter Filter
{
get { return (Filter)GetValue(FilterProperty); }
set { SetValue(FilterProperty, value); }
}
public string FilterStatement
{
get { return (string)GetValue(FilterStatementProperty); }
set { SetValue(FilterStatementProperty, value); }
}
public Class2 MyClass2Instance { get; set; }
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var c = (Class1)d;
if (c.MyClass2Instance?.MyClass3Instance != null)
{
if (e.Property == FilterProperty)
{
c.FilterStatement = c.MyClass2Instance.MyClass3Instance.MyFilterToStatementConversionMemberFunction((Filter)e.NewValue);
}
else if (e.Property == FilterStatementProperty)
{
c.Filter = c.MyClass2Instance.MyClass3Instance.MyStatementToFilterConversionMemberFunction((string)e.NewValue);
}
}
}
}
Please note, Filter.Equals
should be implemented properly and conversion methods of the Class3
should return the equal values for equal arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With