#xaml #data-binding #uwp #binding #programmatically
#xaml #привязка данных #uwp #привязка #программно
Вопрос:
я разрабатываю с помощью uwp, и у меня проблема с привязкой данных. У меня есть ListView, который я заполняю пользовательскими элементами панели, называемыми классом PlaylistLeftOption. Этот класс наследует атрибуты класса Panel, которые наследуют атрибут класса FrameworkElement и его методы, поэтому у меня есть доступный метод привязки. Теперь я пытаюсь привязать значение высоты (оно равно другим элементам), поэтому я создал статический атрибут, называемый PerformanceItemHeight, в другом внешнем одноэлементном классе. поскольку мне нужно динамически заполнять listview, я пытаюсь привязать значение внутри конструктора, но это не работает. Это код внутри конструктора:
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);
}
И это свойство:
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;
}
}
Это код для 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();
}
}
Почему это работает через xaml?
я попытался добавить элемент PlaylistLeftOption внутри listview через xaml, и все в порядке!
Спасибо
Ответ №1:
При тестировании привязка HeightVal
работает в XAML, а привязка HeightVal
не работает в коде. Вы можете увидеть причину в разделе Реализация оболочки свойств пользовательских зависимостей документа, в котором говорится, что ваши реализации оболочки должны выполнять только операции GetValue и setValue . В противном случае вы получите другое поведение, когда ваше свойство задается с помощью XAML, по сравнению с тем, когда оно задается с помощью кода.
Вы могли бы добавить метод обратного вызова с измененным свойством, чтобы активно уведомлять об изменениях HeightVal
.
Например:
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;
}
}
И измените код привязки следующим образом:
var myBinding = new Binding();
myBinding.Source = PerformanceLayout.Instance;
myBinding.Path = new PropertyPath("PerformanceItemHeight");
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
myBinding.Mode = BindingMode.TwoWay;
SetBinding(HeightValProperty, myBinding);
Комментарии:
1. Янгу большое вам спасибо! Он работает правильно!
2. Если ответ решил вашу проблему, пожалуйста, отметьте его как принятый