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
Related
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);
I have a question - I was coding happily a quick little feature to an app, which was a simple comparison output window.
Basically, user clicks a button and I generate a window with a datagrid of two columns of data.
It's all great and a five minutes code living inside one method with no unnecessary reference to anything else. The only problem I encountered was when I wanted to add a TopMost checkbox to this window.
How do I bind the IsChecked property of the box to the TopMost property of the window?
var checkbox = new CheckBox();
checkbox.Name = "cb";
checkbox.Content = "Top most";
var grid = new DataGrid();
grid.ItemsSource = wcList;
grid.Margin = new Thickness(5);
var panel = new StackPanel();
panel.Children.Add(checkbox);
panel.Children.Add(grid);
var win = new Window();
//Binding b = new Binding("cb");
//b.Mode = BindingMode.TwoWay;
//b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
//win.SetBinding(Window.TopmostProperty, b);
win.Title = "WordCount comparison";
win.Content = panel;
win.SizeToContent = SizeToContent.WidthAndHeight;
win.Icon = this.Icon;
win.Show();
This was supposed to be a 5-minutes one-off method, which is why I don't want to go as far as adding any xaml or properties into the code.
Cheers
Bartek
The other way around as you tried (in the commented code):
checkbox.SetBinding(CheckBox.IsCheckedProperty, new Binding("Topmost") { Source = win });
just after you instantiated your win variable.
I have a ScatterViewItem, which contains a UserControl. I'm trying to bind the MinWidth of the ScatterViewItem to the UserControl.
ScatterViewItem svi = new ScatterViewItem();
MyUserControl myUserControl = new MyUserControl();
//Make UC follow SVI's size. This code works.
myUserControl.SetBinding(UserControl.WidthProperty, svi.Width.ToString());
myUserControl.SetBinding(UserControl.HeightProperty, svi.Height.ToString());
//Make SVI follow UC's Min size. This doesn't work.
svi.SetBinding(ScatterViewItem.MinWidthProperty, myUserControl.MinWidth.ToString());
svi.SetBinding(ScatterViewItem.MinHeightProperty, myUserControl.MinHeight.ToString());
svi.Content = myUserControl;
myScatterView.Items.Add(svi);
Why is it that binding UC to SVI works and not the other way? How do I bind the MinWidth of the SVI to the UC then?
The SetBinding method has 2 overloads (source: http://msdn.microsoft.com/en-us/library/ms598270(v=vs.110).aspx):
SetBinding(DependencyProperty, String)
SetBinding(DependencyProperty, BindingBase)
What you are trying to achieve by using the ToString() is not working, since the ToString() converts the value of the (Min)Width and (Min)Height properties to a string (for example 500.0 => "500.0"). The SetBinding overload that accepts a string as second parameter expects that string to be a property name or a path to the property.
What you probably want, is "MinWidth", "Width", "MinHeight" or "Height":
myUserControl.SetBinding(UserControl.WidthProperty, "Width");
myUserControl.SetBinding(UserControl.HeightProperty, "Height");
svi.SetBinding(ScatterViewItem.MinWidthProperty, "MinWidth");
svi.SetBinding(ScatterViewItem.MinHeightProperty, "MinHeight");
Edit: this is the correct version, using the other overload, since the previous piece of code doesn't know where to find the specified properties.
Binding widthBinding = new Binding("Width");
widthBinding.Source = myUserControl;
svi.SetBinding(ScatterViewItem.MinWidthProperty, widthBinding);
Binding heightBinding = new Binding("Height");
heightBinding.Source = myUserControl;
svi.SetBinding(ScatterViewItem.MinHeightProperty, heightBinding);
To bind your ScatterViewItem's MinWidth to your usercontrol's MinWidth, you need to create a binding with the source set to the usercontrol and path set to "MinWidth". This binding is then assigned to the ScatterViewItem with SetBinding.
// Create Binding
Binding b = new Binding("MinWidth");
b.Source = myUserControl;
// Assign Binding to ScatterViewItem
svi.SetBinding(ScatterViewItem.MinWidthProperty, b);
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 });
I try to bind a translateTransform and a compositeTransform together in silverlight 4 in the code (c#). I can't do this in xaml because the UIelements are loaded dynamically. I just need the Xoffset. The compositeTransform is the source. I have the flowing code, but it doesn't work:
TranslateTransform trans = new TranslateTransform();
Binding transBind = new Binding("Value");
transBind.Source = ((CompositeTransform)SchedulePanel.RenderTransform);
BindingOperations.SetBinding(trans, TranslateTransform.XProperty, transBind);
line.TextChannelName.RenderTransform = trans;
Thanks
Looks to me as though:-
Binding transBind = new Binding("Value");
should be
Binding transBind = new Binding("TranslateX");
a composite transform does not have a "Value" property.
Since TranslateTransform is not a FrameworkElement, in order to be the target of a binding it must meet one of these conditions (from MSDN):
In Silverlight 4, the target can also be a DependencyProperty of a DependencyObject in the following cases:
The DependencyObject is the value of a property of a FrameworkElement.
The DependencyObject is in a collection that is the value of a FrameworkElement property (for example, the Resources property).
The DependencyObject is in a DependencyObjectCollection.
So try setting the trans TranslateTransform as the Transform of TextChannelName before setting the binding so that at the moment of setting the binsing, the target.
Try:
TranslateTransform trans = new TranslateTransform();
line.TextChannelName.RenderTransform = trans;
Binding transBind = new Binding("Value");
transBind.Source = ((CompositeTransform)SchedulePanel.RenderTransform);
BindingOperations.SetBinding(trans, TranslateTransform.XProperty, transBind);