При отладке проблемы в приложении WPF я заметил, что привязка данных TwoWay
не кажется симметричной. Вот пример:Как получить симметричную привязку TwoWay?
<Window x:Class="ConverterTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ConverterTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:TextConverter x:Key="textConverter"/>
</Window.Resources>
<Grid>
<TextBox x:Name="txt1" Height="24" Margin="0" VerticalAlignment="Top"/>
<TextBox x:Name="txt2" Height="24" Margin="0,40,0,0" VerticalAlignment="Top"
Text="{Binding ElementName=txt1, Path=Text,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource textConverter}}"/>
</Grid>
</Window>
Преобразователь выглядит следующим образом:
public class TextConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, System.Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
return value.ToString().ToUpper();
}
public object ConvertBack(object value, System.Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
return value.ToString().ToLower();
}
#endregion
}
При редактировании внутри txt1
только Convert()
называется; но при редактировании внутри txt2
, сначала ConvertBack()
, а затем Convert()
.
Другими словами, TwoWay
связывание, кажется, работает так:
- Если свойство источника обновляется, свойство цели обновляется.
- Когда свойство target обновляется, сначала обновляется свойство source, а затем свойство target обновляется снова.
MSDN documentation просто говорит:
Причина изменения либо свойства источника или целевое свойство для автоматического обновления других.
Из этого предложения, я бы ожидал следующее поведение:
- Если свойство источника обновляется, свойство цели обновляется.
- Когда свойство target обновляется, свойство source обновляется.
Есть ли способ достичь этого симметричного поведения (только в XAML, без программирования на C#)?
EDIT: Я только что обнаружил, что в WPF 3.5, TwoWay
крепления работают симметрично. Однако в WPF 4.0 поведение изменилось (как описано выше).
Это поведение, на мой взгляд, согласуется с документацией. txt2 является источником самого себя - подумайте о последствиях, если это не так. Если вы хотите, чтобы txt2 не был источником, тогда привяжите его в будущем и используйте текстовый блок. – Paparazzi
@Blam: Я думаю, что есть веские причины как для несимметричной, так и для симметричной привязки TwoWay. В моем примере выше, если вы вводите строчные буквы в txt2, они неожиданно преобразуются в верхние буквы внутри txt2 во время ввода. В этом конкретном примере это не имеет большого значения, но могут быть и другие, более сложные привязки (например, форматирование даты/времени), где пользователи, конечно, будут раздражаться, когда WPF переформатирует напечатанный текст. Этого можно легко избежать с помощью симметричной привязки TwoWay. –
@Blam - Это легко избежать/выполнимо/решено путем отказа от требования «нет C#». –