Блог Карла Шиффлетта и ответ @ Simpzon уже охватывают, почему они добавили эту функцию и почему это не проблема для свойств, которые всегда получают то, что было установлено. В вашем собственном коде вы всегда используете промежуточное свойство, которое имеет правильную семантику для связывания, и используете внутреннее свойство, которое имеет желаемую семантику. Я бы назвал промежуточное свойство «блокирующим» свойством, потому что оно блокирует геттер от достижения вашего внутреннего свойства.
Но в случае, если у вас нет доступа к исходному коду для сущности, для которой вы устанавливаете свойство, и вам нужно старое поведение, вы можете использовать конвертер.
Вот блокирующий конвертер с состоянием:
public class BlockingConverter : IValueConverter
{
public object lastValue;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return lastValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
lastValue = value;
return value;
}
}
и вы можете использовать его для своего примера следующим образом:
<Grid>
<Grid.Resources>
<local:BlockingConverter x:Key="blockingConverter" x:Shared="False"/>
</Grid.Resources>
<StackPanel>
<TextBox Text="{Binding TextProperty, Mode=OneWayToSource, Converter={StaticResource blockingConverter}}"/>
<Button Content="Click"/>
</StackPanel>
</Grid>
Обратите внимание, что, поскольку конвертер имеет состояние, вам нужен отдельный экземпляр при каждом использовании ресурса, и для этого мы можем использовать атрибут x:Shared="False"
для ресурса.