Get Binding from a FrameworkElementFactory - c#

In a GirdView the text of some columns sould be aligned to the right.
To do that I create a DataTemplate, which contains a TextBlock.
Binding bd = new Binding("path");
FrameworkElementFactory tbContent = new FrameworkElementFactory(typeof(TextBlock));
tbContent.SetBinding(TextBlock.TextProperty, bd);
tbContent.SetValue(TextBlock.TextAlignmentProperty, TextAlignment.Right);
DataTemplate dataTemplate = new DataTemplate();
dataTemplate.VisualTree = tbContent;
myGridViewColumn.CellTemplate = dataTemplate;
In an other class I have to access the Bindings of my GridViewColumns. How can I access the Binding of this column?

I had the same issue, so I exposed the TextAlignmentProperty as a public property.

Related

wpf dynamic border thickness binding

I have a border generated dynamically.
I want to bind thickness property of it, with my style model.
Border db = new Border();
Binding borderthickness = new Binding();
borderthickness.Source = this.imodel.GridStyleProperties.BorderThickness;
borderthickness.Path = new PropertyPath("BorderThickness");
BindingOperations.SetBinding(db, Border.BorderThicknessProperty, borderthickness);
This is what I have done so far. Its not working for me.
Please suggest me what is wrong with this code.
Thank you
You are binding to a BorderThickness object, with Path set to BorderThickness. That means the binding will look in this.imodel.GridStyleProperties.BorderThickness.BorderThickness which doesn't exist.
Try
borderthickness.Source = this.imodel.GridStyleProperties;
borderthickness.Path = new PropertyPath("BorderThickness");
or just
borderthickness.Source = this.imodel.GridStyleProperties.BorderThickness;

Converter not working when DataTemplate is loaded in code behind

I loaded the datatemplate for image column in code behind . Please refer the below code snippet,
FrameworkElementFactory fef = new FrameworkElementFactory(typeof(Image));
Binding bind = new Binding() { Path=new PropertyPath(imagecolumn.MappingName),Converter = new StringToImageConverter(),Mode=BindingMode.TwoWay };
fef.SetBinding(Image.SourceProperty,new Binding(imagecolumn.MappingName));
DataTemplate template = new DataTemplate() { VisualTree = fef };
this.imagecolumn.CellItemTemplate = template;
But my converter is not invoked. I need to load different images in each row of the column . Am i missed anything ? Please share any idea
You instantiate a new Binding but you never use it. Do this:
FrameworkElementFactory fef = new FrameworkElementFactory(typeof(Image));
Binding bind = new Binding() { Path=new PropertyPath("MappingName"),Converter = new StringToImageConverter(),Mode=BindingMode.TwoWay,Source=imagecolumn };
fef.SetBinding(Image.SourceProperty, bind); // here you just created
//another instance of Binding instead of using your bind variable
DataTemplate template = new DataTemplate() { VisualTree = fef };
this.imagecolumn.CellItemTemplate = template;
EDIT:
Have a look at FrameworkElementFactory. In the remarks it sais:
This class is a deprecated way to programmatically create templates, which are subclasses of FrameworkTemplate such as ControlTemplate or DataTemplate; not all of the template functionality is available when you create a template using this class. The recommended way to programmatically create a template is to load XAML from a string or a memory stream using the Load method of the XamlReader class.
Maybe you should do it the recommended way.

Binding a user control text property in code-behind

I'm trying to create a custom control which inherits from a TextBox control. in the constructor of my custom control I need to have the text property bound. this the code I'm using by now.
var binding = new Binding("Name");
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
binding.ValidatesOnDataErrors = true;
SetValue(TextProperty, binding);
I haven't set a source for binding because I want it be the DataContext of the form on which my custom control will be placed however I suppose I'm doing it in a wrong way because when I added on the form I face the error message in xaml which says: "System.Windows.Data.Binding is not a valid value for property text.
Its not good to do in code-behind, hope this answers your question
Binding binding = new Binding();
binding.Path = new PropertyPath("yourPropertyTobeBinded");
binding.Source = sourceObject;
BindingOperations.SetBinding(youTextBox, TextBox.TextProperty, binding);

How do you set binding of ComboBox ItemsSource in UserControl?

Here is the combobox in my UserControl:
<Combobox ItemsSource="{Binding ComboItemsProperty}" />
I have tried:
Binding bind = new Binding();
bind.Mode = BindingMode.OneWay;
bind.Source = this;
bind.Path = new PropertyPath("ComboItemsProperty");
this.SetBinding(ComboBox.ItemsSourceProperty, bind);
However, this doesn't work. I think I am doing the bind.Source wrong, but I'm not sure what to set the Source to. This code is inside my UserControl.xaml.cs.
You can try (Replace this)
Binding bind = new Binding();
bind.Mode = BindingMode.OneWay;
bind.Source = yourCollectionSourceOrClass; //<--Replace with your collection
bind.Path = new PropertyPath("ComboItemsProperty");
this.SetBinding(ComboBox.ItemsSourceProperty, bind);
You need to the set context of the instance containing your property ComboItemsProperty. So instead of 'this' u should set it to 'this.DataContext' or other class object instance containing the ItemSource property you have defined..
Try this,
Binding bind = new Binding();
bind.Mode = BindingMode.OneWay;
bind.Source = this.DataContext;
bind.Path = new PropertyPath("ComboItemsProperty");
this.SetBinding( ComboBox. ItemsSource Property, bind);
(posting frm mobile)
I have tried a lot of ways to do this, however, nothing seems to work.
I am instead going to serialize the binding when the .xaml file gets saved out. This seems to be working perfectly. Binding will no longer have to be set in code.

How do I build a DataTemplate in c# code?

I am trying to build a dropdown list for a winform interop, and I am creating the dropdown in code. However, I have a problem getting the data to bind based on the DataTemplate I specify.
What am I missing?
drpCreditCardNumberWpf = new ComboBox();
DataTemplate cardLayout = new DataTemplate {DataType = typeof (CreditCardPayment)};
StackPanel sp = new StackPanel
{
Orientation = System.Windows.Controls.Orientation.Vertical
};
TextBlock cardHolder = new TextBlock {ToolTip = "Card Holder Name"};
cardHolder.SetBinding(TextBlock.TextProperty, "BillToName");
sp.Children.Add(cardHolder);
TextBlock cardNumber = new TextBlock {ToolTip = "Credit Card Number"};
cardNumber.SetBinding(TextBlock.TextProperty, "SafeNumber");
sp.Children.Add(cardNumber);
TextBlock notes = new TextBlock {ToolTip = "Notes"};
notes.SetBinding(TextBlock.TextProperty, "Notes");
sp.Children.Add(notes);
cardLayout.Resources.Add(sp, null);
drpCreditCardNumberWpf.ItemTemplate = cardLayout;
Assuming that you've already set up the ItemsSource etc for drpCreditCardNumberWpf...
//create the data template
DataTemplate cardLayout = new DataTemplate();
cardLayout.DataType = typeof(CreditCardPayment);
//set up the stack panel
FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(StackPanel));
spFactory.Name = "myComboFactory";
spFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
//set up the card holder textblock
FrameworkElementFactory cardHolder = new FrameworkElementFactory(typeof(TextBlock));
cardHolder.SetBinding(TextBlock.TextProperty, new Binding("BillToName"));
cardHolder.SetValue(TextBlock.ToolTipProperty, "Card Holder Name");
spFactory.AppendChild(cardHolder);
//set up the card number textblock
FrameworkElementFactory cardNumber = new FrameworkElementFactory(typeof(TextBlock));
cardNumber.SetBinding(TextBlock.TextProperty, new Binding("SafeNumber"));
cardNumber.SetValue(TextBlock.ToolTipProperty, "Credit Card Number");
spFactory.AppendChild(cardNumber);
//set up the notes textblock
FrameworkElementFactory notes = new FrameworkElementFactory(typeof(TextBlock));
notes.SetBinding(TextBlock.TextProperty, new Binding("Notes"));
notes.SetValue(TextBlock.ToolTipProperty, "Notes");
spFactory.AppendChild(notes);
//set the visual tree of the data template
cardLayout.VisualTree = spFactory;
//set the item template to be our shiny new data template
drpCreditCardNumberWpf.ItemTemplate = cardLayout;
You can use the same way I have set the ToolTip on the TextBlocks to set other properties such as margins.
The full version
var ms = new MemoryStream(Encoding.UTF8.GetBytes(#"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:c=""clr-namespace:MyApp.Converters;assembly=MyApp"">
<DataTemplate.Resources>
<c:MyConverter x:Key=""MyConverter""/>
</DataTemplate.Resources>
<TextBlock Text=""{Binding ., Converter={StaticResource MyConverter}}""/>
</DataTemplate>"));
var template = (DataTemplate)XamlReader.Load(ms);
var cb = new ComboBox { };
//Set the data template
cb.ItemTemplate = template;
Well, indeed we still have another way, you will really like it if you dislike those FrameworkElementFactory things.
And I think it just makes minor changes to the natural code, that is, declare a UserControl and put your control into it, and then, use just one FrameworkElementFactory to call the UserControl.
Simple demo code (in F#):
let buildView()=StackPanel()
//Build it with natural code
type MyView()=inherit UserControl(Content=buildView())
let factory=FrameworkElementFactory(typeof<MyView>)
let template=DataTemplate(VisualTree=factory)
let list=ItemsControl(ItemsSource=makeData(),ItemTemplate=template)

Categories