OneWayToSource binding resetting target value - c#

Why is the OneWayToSource binding resetting my target value?
Here is the binding code:
SolidColorBrush brush = GetTemplateChild("PART_PreviewBrush") as SolidColorBrush;
if (brush != null)
{
Binding binding = new Binding("Color");
binding.Source = brush;
binding.Mode = BindingMode.OneWayToSource;
this.SetBinding(ColorPicker.ColorProperty, binding);
}
I set the "Color" dependency property in xaml. But it gets overwritten by the binding. After that the binding works ok.
So, essentially my problem is: I can't give a starting value to the "Color" property because it gets overwritten by the binding.
EDIT:
I made a workaround that solves the problem, but still don't understand why OneWayToSource behaves like that:
System.Windows.Media.Color CurrentColor = this.Color;
this.SetBinding(ColorPicker.ColorProperty, binding);
this.Color = CurrentColor;
EDIT 2:
Found a possible solution:
I have to set:
binding.FallbackValue = this.Color;

You could use the BindingOperations class to set the binding:
BindingOperations.SetBinding(
brush, SolidColorBrush.ColorProperty, new Binding("Color") { Source = this });

Related

WPF Set a TextBox property in code-behind

Hi I want to set the Text property of a Textbox by code behind. At the moment I do using XAML:
<TextBox x:Name="txtFilter" Text="{Binding FiltroFunzioni, Mode=OneWayToSource}" Grid.Row="0" />
As test I did this:
Binding b = new Binding();
b.Mode = BindingMode.OneWayToSource;
b.Path = new PropertyPath("Text"); //??
b.Source = PageViewModel.FiltroFunzioni;
BindingOperations.SetBinding(txtFilter, TextBlock.TextProperty, b);
The variable "FiltroFunzioni" is a string defined as property:
private string _filtroFunzioni = "";
public string FiltroFunzioni
{
get { return _filtroFunzioni; }
set
{
_filtroFunzioni = value;
RaisePropertyChanged("FiltroFunzioni");
_functionsView.Refresh();
}
}
Basically I dunno what kind of value should I set as PropertyPath. Any ideas?
You don't need the PropertyPath here. If you just remove it, your binding should work.
That being said, you should bind in XAML wherever possible.
If your issue is that changes to FiltroFunzioni don't update your textbox, that's because your binding is specifically declared as OneWayToSource: that means that changing the UI changes the source, but changing the source doesn't change the UI. If that isn't what you want, set the Mode to something else, like "TwoWay" - then changes to the source change the UI, AND changes to the UI change the source.
EDIT:
If you really want to bind from your ViewModel instead of just using XAML, TwoWay binding requires utilizing the Path for some reason, when binding through C#. Either of the following solutions work:
b.Source = FiltroFunzioni;
b.Path = new PropertyPath(".");
b.Source = this;
b.Path = new PropertyPath("FiltroFunzioni");
Note that with TwoWay binding you have to either initialize your FiltroFunzioni by setting the TextBox.Text property in your XAML, or setting FiltroFunzioni after the binding was initialized. Otherwise, WPF will immediately override it from the (by default empty) Text in your TextBox.

How to properly use a binding in C#

I want to bind the background of a WPF Rectangle to the Brush property of another element.
The initialization looks like this:
MazeElement nextElement = new MazeElement();
nextElement.Position = new Point(xIndex, yIndex);
nextElement.BackgroundColor = Brushes.Aqua;
MazeElements.Add(nextElement);
Binding bg = new Binding {Source = MazeElements[Index(xIndex, yIndex)]};
Rectangle nextRect = new Rectangle();
nextRect.Height = MazeGridSize;
nextRect.Width = MazeGridSize;
nextRect.Fill = Brushes.White;
nextRect.Stroke = Brushes.Gray;
nextRect.StrokeThickness = 2;
nextRect.SetBinding(Shape.FillProperty, bg);
temp.Children.Add(nextRect);
Canvas.SetLeft(nextRect, xIndex * MazeGridSize);
Canvas.SetTop(nextRect, yIndex * MazeGridSize);
Where is my mistake? I don't understand how to use the Binding from the C# side.
First, you are not providing us with enough information. We cannot see the full nature of the type MazeElement. But I assume that the BackgroundColor is a Property on the MazeElement class
Second, the binding has a Source, an object in your case nextElement, and the a PropertyPath, in your case the BackgroundColor. Therefore your binding object should be:
Binding bg = new Binding {Source = nextElement, Path = new PropertyPath("BackgroundColor") };
In your case the source property is of the same type as the target dependency property, so the above will do what you want. If it was not the case, you can set a converter on the binding - Look that up, if you need that in another situation

Binding on a nested property without using XAML

How to make a binding on a nested target property, like Shape.Stroke.Color in WPF without using XAML ?
For a simple property I'm using a code looking like this :
var binding = new Binding("mySourceProperty");
binding.Source = mySourceObject;
myTargetObject.SetBinding(myTargetProperty, binding);
Where myTargetProperty can be, for example, Shape.StrokeProperty.
But now, how can I do the same thing on the ColorProperty of the Stroke of a Shape ?
Provided that the Shape's Stroke property holds a SolidColorBrush, you can use the static BindingOperations.SetBinding method:
var shape = new Path(); // or whatever
var binding = new Binding { Source = Colors.Red }; // or whatever
BindingOperations.SetBinding(shape.Stroke, SolidColorBrush.ColorProperty, binding);

How to programmatically bind Visibility on a button to INotifyPropertyChanged boolean property in C#?

Here's what I got to so far:
System.Windows.Data.Binding binding = new System.Windows.Data.Binding("MyProperty");
binding.Mode = System.Windows.Data.BindingMode.TwoWay;
binding.Converter = new System.Windows.Controls.BooleanToVisibilityConverter();
binding.Source = mySourceObject;
this.SetBinding(this.myButton.Visibility, binding);
but visibility is not a dependency property, so how can I do this?
You should be able to do
Button.VisibilityProperty
instead of
this.myButton.Visibility
http://msdn.microsoft.com/en-us/library/system.windows.uielement.visibilityproperty.aspx
You need to pass in the static Visibility dependency property itself (which Button inherits from UIElement), not the value of the property on the button instance, e.g.:
myButton.SetBinding(UIElement.VisibilityProperty, binding);

How to bind RadDataPager.PageSize to RadNumericUpDown.Value in code

I have a RadGridView, a RadDataPager and a RadNumericUpDown all defined in code.
Now i want to bind the RadDataPager.PageSize to the RadNumericUpDown.Value so the pagesize of the pager is changeable via the RadNumericUpDown control.
Thus i try:
RadDataPager dataPager = new ...;
RadNumericUpDown pageSizeSelector = new ...;
Binding b = new Binding();
b.Mode = BindingMode.TwoWay;
b.Source = pageSizeSelector.Value;
pageSizeSelector.SetBinding(dataPager.PageSize, b);
But this generates an error about the dataPager.PageSize not being a DependencyProperty. What i'm a missing?
EDIT
Thanks to Klinger i got it straight. SetBinding wants the Static Definition of the DP, not a reference to the instance.
Binding b = new Binding("PageSize");
b.Mode = BindingMode.TwoWay;
b.Source = dataPager;
pageSizeSelector.SetBinding(RadNumericUpDown.ValueProperty, b);
Only dependency properties know how to handle binding expressions.
Take a look on the control documentation to see if the PageSize property is a dependency property.

Categories

Resources