#.net #wpf #wpf-controls #binding
#.net #wpf #wpf-элементы управления #привязка
Вопрос:
Я создаю пользовательский элемент управления в WPF, который я называю YesNoButton.
Она имеет единственное свойство DependencyProperty, проверенное IsChecked, и содержит две кнопки переключения с метками «Да» и «Нет». Я привязал свойство IsChecked кнопки переключения Yes к этому свойству IsChecked родительского YesNoButton. Я привязал свойство IsChecked кнопки переключения No к свойству IsChecked кнопки переключения Yes с помощью ‘обратного логического значения’ IValueConverter. Вот моя разметка YesNoButton, за вычетом некоторых излишеств во внешнем виде:
<UserControl ...>
<StackPanel Orientation="Horizontal">
<ToggleButton x:Name="YesButton" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type Controls:YesNoButton}}, Path=IsChecked}">Yes</ToggleButton>
<ToggleButton IsChecked="{Binding ElementName=YesButton, Path=IsChecked, Converter={StaticResource BooleanToInverseConverter}}">No</ToggleButton>
</StackPanel>
</UserControl>
В моем приложении я включаю YesNoButton следующим образом:
<local:YesNoButton IsChecked="{Binding Path=BoolPropertyOfDataContext}" />
При первой загрузке окна, если я переключаю BoolPropertyOfDataContext другими способами, YesNoButton реагирует идеально.
Но как только я нажимаю кнопку переключения «Да» или «Нет», хотя визуальное состояние YesNoButton обновляется правильно, привязка к BoolPropertyOfDataContext вообще перестает работать — похоже, она отменена. Я думал, что эти «цепочки привязок» должны были работать нормально, но я, очевидно, чего-то здесь не хватает!
Есть идеи?
Ответ №1:
Два предложения:
- Назовите свой UserControl, чтобы вы могли ссылаться на него
- Привязать оба состояния ToggleButton IsChecked к свойству IsChecked для UserControl
Например:
<StackPanel Orientation="Horizontal">
<ToggleButton IsChecked="{Binding ElementName=YesNoButton, Path=IsChecked}">Yes</ToggleButton>
<ToggleButton IsChecked="{Binding ElementName=YesNoButton, Path=IsChecked, Converter={StaticResource BooleanToInverseConverter}}">No</ToggleButton>
</StackPanel>
Комментарии:
1. Спасибо. Уже пробовал (1) — никакой разницы. Я попытался полностью удалить переключатель No, но это все равно не сработало, поэтому я предполагаю, что (2) не поможет. Я знаю, что в прошлом, когда я вручную устанавливал свойству IsChecked элемента управления некоторое значение, его привязки были уничтожены. Я предполагаю, что здесь происходит нечто подобное, но я не могу понять, что.
2. Как реализован BoolPropertyOfDataContext? Является ли это свойством зависимости? Кроме того, замечаете ли вы какие-либо сообщения в окне вывода, если запускаете под управлением отладчика?
3. BoolPropertyOfDataContext — это логическое поле объекта Entity Framework Entity (и поэтому имеет уведомление об изменении свойства). К сожалению, в окне вывода нет сообщений!
4. Получилось совершенно по-другому (см. Мой отредактированный пост), но я до сих пор не знаю, почему моя первая попытка не сработала!
Ответ №2:
Я заставил это работать, установив вместо этого флажок:
<CheckBox IsChecked="{Binding Path=BoolPropertyOfDataContext}" Style="{StaticResource YesNoButton}" />
<Style x:Key="YesNoButton" TargetType="{x:Type CheckBox}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<StackPanel Orientation="Horizontal">
<ToggleButton x:Name="YesButton" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type CheckBox}}, Path=IsChecked}">Yes</ToggleButton>
<ToggleButton IsChecked="{Binding ElementName=YesButton, Path=IsChecked, Converter={StaticResource BooleanToInverseConverter}}">No</ToggleButton>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>