Onewaytosource Binding Seems Broken in .Net 4.0

OneWayToSource Binding seems broken in .NET 4.0

Karl Shifflett's blog and @Simpzon's answer already cover why they added this feature and why it is not a problem for properties that always get what was set. In your own code you always use an intermediate property that has the proper semantics for binding and use an internal property that has the semantics you want. I would call the intermediate property a "blocking" property because it blocks the getter from reaching your internal property.

But in the case where you don't have access to the source code for the entity that you are setting the property on and you want the old behavior, you can use a converter.

Here is a blocking converter with state:

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;
}
}

and you can use it for your example like this:

<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>

Note that because the converter has a state you need a separate instance each time the resource is used and for this we can use the x:Shared="False" attribute on the resource.

Binding OnwayToSource not working as expected - what alternatives?

I've finally realized what you're trying to do, and you're right that it should work. WPF, however, disagrees. I see that it's a problem that others have had before, but that is apparently by design. You can't set up a binding on a read only property, even if you're just wanting to bind OneWayToSource.

Here is a question with the same problem: OneWayToSource binding from readonly property in XAML Their workaround was to put a container (which has read/write width/height) around the xaml element and set up the binding on that container. This might work for you.

There is an unresolved issue related to this on Microsoft Connect where it is claimed to be behaviour by design: http://connect.microsoft.com/VisualStudio/feedback/details/540833/onewaytosource-binding-from-a-readonly-dependency-property. Someone claims a workaround in the related thread which uses a converter. You can try it, but I'm not sure it'll work in your case, as their binding was to a custom control, not a built in framework element.

Even Better

In This Solution, Boogaart came up with an implementation defining a new attached property (Similar to DockPanel.Dock="Top") which allows any element to provide its width and height for observation:

<TextBlock ...
SizeObserver.Observe="True"
SizeObserver.ObservedWidth="{Binding Width, Mode=OneWayToSource}"
SizeObserver.ObservedHeight="{Binding Height, Mode=OneWayToSource}"

Try it on and see if it fits.

WPF Binding, OneWayToSource, Property Get method was not found.

I tried something out and the code below works. I hope this helps:

Code-Behind:


public partial class MainWindow : Window
{
private SomeCustomType registry;
public SomeCustomType Registry { set { registry = value; } }

public MainWindow()
{
InitializeComponent();
this.comboBox.DataContext = this;
}

}

public class SomeType
{
public static SomeCustomType Property1 { get { return new SomeCustomType() { Name = "Item1" }; } }
public static SomeCustomType Property2 { get { return new SomeCustomType() { Name = "Item2" }; } }
}

public class SomeCustomType
{
public string Name { get; set; }
}

XAML:

<ComboBox x:Name="comboBox" SelectedValue="{Binding Registry, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" 
SelectedValuePath="Tag" SelectedIndex="0">
<ComboBoxItem Content="Item1" Tag="{x:Static local:SomeType.Property1}" />
<ComboBoxItem Content="Item2" Tag="{x:Static local:SomeType.Property2}" />
</ComboBox>

WPF binding OneWayToSource sets source property to when the DataContext is changed

Its a bug or perhabs not. Microsoft claims its by design. You first type x and then you kill DataContext by clicking on Button hence why the TextBox holds x and your viewModel.Text property gets newly initialized (its empty). When on datacontext changed getter will still be called. In the end you have no chance to fix this.

You can however use two way and let it be.

Unable to use OneWayToSource binding in a Silverlight application

It is not available in Silverlight. You consulted the wrong page (full .Net).

[Edit] You can simulate it with a TwoWay-Binding and a ValueConverter that discards any input in its Convert method:

public class DiscardingConverter : IValueConverter
{
public object Convert(...)
{
return DependencyProperty.UnsetValue;
}
}

UnsetValue

WPF TargetNullValue returning value when the textbox's binding is set to OneWayToSource

This is because WPF re-reads the value from the property after it sets it even though the binding is OneWayToSource. Please see the answer to this question for possible workaround.



Related Topics



Leave a reply



Submit