Reputation: 159
i'm developing with uwp and i've a problem with data binding. I have a listView that i fill with a custom panel elements called PlaylistLeftOption class. This class inherit Panel class attributes that inherit FrameworkElement class attribute and its methods so i have a SetBinding method avaible. Now i'm trying to bind the height value (it's equal to other elements) so i created a static attribute, called PerformanceItemHeight, in other extern singleton class. since i need to fill listview dinamically i'm trying to bind the value inside the constructor but it don't work. This is the code inside constructor:
public PlaylistLeftOption()
{
mainGrid.Background = new SolidColorBrush(Colors.Red);
mainGrid.BorderBrush = new SolidColorBrush(Colors.Black);
mainGrid.BorderThickness = new Thickness(0.5,0.25,0.5,0.25);
WidthVal = 200;
HeightVal = 50;
var myBinding = new Binding();
myBinding.Source = PerformanceLayout.Instance.PerformanceItemHeight;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
myBinding.Mode = BindingMode.TwoWay;
SetBinding(HeightValProperty, myBinding);
Children.Add(mainGrid);
}
And this is the property:
public static readonly DependencyProperty HeightValProperty = DependencyProperty.Register(
"HeightVal",
typeof(double),
typeof(PlaylistLeftOption),
new PropertyMetadata(50)
);
public double HeightVal
{
get => (double)GetValue(HeightValProperty);
set
{
SetValue(HeightValProperty, value);
Height = HeightVal;
mainGrid.Height = HeightVal;
globalSize.Height = HeightVal;
}
}
This is the code for PerformanceItemHeight:
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
// Raise the PropertyChanged event, passing the name of the property whose value has changed.
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private double _performanceItemHeight = 50;
public double PerformanceItemHeight {
get => _performanceItemHeight;
set {
_performanceItemHeight = value;
this.OnPropertyChanged();
}
}
Why does via xaml it works? i tryied to add PlaylistLeftOption item inside listview via xaml and it's ok! thank you
Upvotes: 0
Views: 223
Reputation: 3032
By testing, the binding of HeightVal
works in XAML and the binding of HeightVal
does not work in code-behind. You could see the reason in the section Implementing the wrapper of the document Custom dependency properties which says that your wrapper implementations should perform only the GetValue and SetValue operations. Otherwise, you'll get different behavior when your property is set via XAML versus when it is set via code.
You could add a property-changed callback method to notify the changes of HeightVal
actively.
For example:
public static readonly DependencyProperty HeightValProperty = DependencyProperty.Register(
"HeightVal",
typeof(double),
typeof(PlaylistLeftOption),
new PropertyMetadata(100, new PropertyChangedCallback(OnHeightValChanged))
);
private static void OnHeightValChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PlaylistLeftOption playlistLeftOption = d as PlaylistLeftOption;
if(playlistLeftOption != null)
{
var height = (Double)e.NewValue;
playlistLeftOption.HeightVal = height;
}
}
And change the binging code like this:
var myBinding = new Binding();
myBinding.Source = PerformanceLayout.Instance;
myBinding.Path = new PropertyPath("PerformanceItemHeight");
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
myBinding.Mode = BindingMode.TwoWay;
SetBinding(HeightValProperty, myBinding);
Upvotes: 1