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);
Related
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
I working on Xamarin project and made custom renderer for my custom control in UWP project. I found how to set the ControlTemplate by using xml code.
XML Way:
var tb = new TextBox(); // or what I do in Xamarin var tb = Control;
var ct = (Controls.ControlTemplate)XamlReader.Load(#"
<ControlTemplate TargetType=""TextBox"" xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Grid>
....
</Grid>
</ControlTemplate>");
tb.Template = ct;
But how I can do the same in code?
var tb = new TextBox(); // or what I do in Xamarin var tb = Control;
var ct = new ControlTemplate();
ct.TargetType = typeof(TextBox);
var grid = new Grid();
ct.VisualTree = grid // This is how it was done in wpf but there is no such option in UWP
tb.Template = ct;
It's not supported in UWP, and I previously found no way to directly set it. As per the MS docs.
ControlTemplate: this is used as the value of the Control.Template
property, which defines the visuals of a control by applying the
template. You almost always define a ControlTemplate as a XAML
resource, using an implicit key TargetType that is the same as a Style
that sets Control.Template with a Setter. You rarely if ever assign a
value for Control.Template directly on a control instance.
Besides possibly delving into reflection, or using the XAMLReader as per your first example, I have never found another way to do it, like you do in WPF.
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 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);
I'm very new to WPF and I'm attempting to create a treelist navigation within each navbar group. Because the number of navbar groups and treelists are dynamic I have to make them in code rather than them be pre-defined in XAML.
I have tested the following so far which is meant to define the navbar group's content rather than use the default item
private void CreateGroup2(NavBarControl navBar)
{
NavBarGroup group2 = new NavBarGroup();
group2.Header = "Custom Content";
//Specify that the group's content should be defined via the Content property
group2.DisplaySource = DisplaySource.Content;
TreeListControl tree = new TreeListControl();
tree.ItemsSource = TreeList_DataBinding.Stuff.GetStuff();
group2.Content = tree;
navBar.Groups.Add(group2);
}
This gives an Exception: Grid.InfiniteGridSizeException: By default, an infinite grid height is not allowed since all grid rows will be rendered and hence the grid will work very slowly. To fix this issue, you should place the grid into a container that will give a finite height to the grid, or you should manually specify the grid's Height or MaxHeight. Note that you can also avoid this exception by setting the TreeListControl.AllowInfiniteGridSize static property to True, but in that case the grid will run slowly.
I'm a little confused as I'm not using a grid? Can anyone give any pointers what's wrong and how I can add a treview under each navbar group?
Thank You
It feels a bit wrong answering my own question but I managed to get it working using the following
private void CreateGroup2(NavBarGroup navBarGroup)
{
System.Windows.Controls.TreeView treeview = new System.Windows.Controls.TreeView();
TreeViewItem nod = new TreeViewItem();
nod.Header = "Tree Node1";
treeview.Items.Add(nod);
TreeViewItem nod1 = new TreeViewItem();
nod1.Header = "Tree Node2";
treeview.Items.Add(nod1);
TreeViewItem nod2 = new TreeViewItem();
nod2.Header = "Tree Node3";
nod1.Items.Add(nod2);
//StackPanel stcPnl = new StackPanel(); /optiona
//stcPnl.Children.Add(treeview);
//navBarGroup.Content = stcPnl;
navBarGroup.Content = treeview;
navBarGroup.DisplaySource = DisplaySource.Content;
}