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);
Related
I'm trying to create a label at runtime and connect it's Content property to another TextBox control which is in my UserControl called MyLabelSettings.
This is what I got so far:
Label currCtrl = new Label();
MyLabelSettings currCtrlProperties = new MyLabelSettings();
// Bindings to properties
Binding binding = new Binding();
binding.Source = currCtrlProperties.textBox_Text.Text;
binding.Path = new PropertyPath(Label.VisibilityProperty);
BindingOperations.SetBinding(currCtrl.Content, Label.ContentProperty, binding);
The last row shows an error which I did not figure out how to solve:
The best overloaded method match for 'System.Windows.Data.BindingOperations. SetBinding(System.Windows.DependencyObject, System.Windows.DependencyProperty, System.Windows.Data.BindingBase)' has some invalid arguments
I have in MyLabelSettings the implementation of INotifyPropertyChanged
which has the following code when the TexBox.Text changes
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
InvokePropertyChanged(new PropertyChangedEventArgs("TextChanged"));
}
Is there a better way to bind these 2? Or am I doing something wrong in this one?
Thanks!
The problem is simpler than you realize:
This:
binding.Source = currCtrlProperties.textBox_Text.Text;
binding.Path = new PropertyPath(Label.VisibilityProperty);
BindingOperations.SetBinding(currCtrl.Content, Label.ContentProperty, binding);
Should be this:
//The source must be an object, NOT a property
binding.Source = currCtrlProperties;
//Since the binding source is not a DependencyObject, we using string to find it's property
binding.Path = new PropertyPath("TextToBind");
BindingOperations.SetBinding(currCtrl, Label.ContentProperty, binding);
Before, you were attempting to bind the value to an object's property via a property. Now, you're binding the value to an object's property via an object (:
Notes:
You are attempting to bind the text of a control that exists in an instance of a class you just made.
MyLabelSettings currCtrlProperties = new MyLabelSettings();
I base this assumption off this line:
currCtrlProperties.textBox_Text.Text;
Which appears to contain a text control of some sort. Rather, you want bind the text of a property that exists in an instance of a class you make, not a control.
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.
I have a UserControl (Map) that contains a Canvas control. I am dynamically adding a control (Gate) to this canvas from the code behind.
I want the Gate objects DataContext to be the "Gate" property of the Map's DataContext. This is being done in the code behind.
Binding dataContextBinding = new Binding();
dataContextBinding.RelativeSource = new RelativeSource(RelativeSourceMode.Self);
dataContextBinding.Path = new PropertyPath("DataContext.SelectedLevelModule.Gate");
dataContextBinding.Mode = BindingMode.TwoWay;
dataContextBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(gate, DataContextProperty, dataContextBinding);
After this block of code runs, the gate.DateContext is null...
Any ways this can be done? Drawing a blank..
Thanks
Harold
You are setting the property path to DataContext.SelectedLevelModule.Gate. You are then assigning the binding to the DataContextProperty. I think what is happening is that the path is now gate.DataContext.DataContext.SelectedLevelModule.Gate.
Try removing DataContext from your PropertyPath and see if that fixes it. You are already assigning it to the DataContext, you should not have to specify it in the Path.
var dataContextBinding = new Binding();
dataContextBinding.Path = new PropertyPath("SelectedLevelModule.Gate");
BindingOperations.SetBinding(gate, DataContextProperty, dataContextBinding);
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.
Could somebody please take some time to show me a quick example on how to bind a text box to the property of an object from c# code? (I've tried to do it on my own, but i can't seem to get it right.)
Thank you guys. I just spent an hour before i realized how stupid i am ( i was setting the wrong object as the biding source).
Thank you all for your help.
Binding b = new Binding();
b.Source = yourObject;
b.Path = new PropertyPath("YourProperty");
yourTextBox.SetBinding( TextBox.TextProperty, b );
There are a lot of other properties on binding you can set. The above does one-way binding, but you can change that by setting the Mode property.
Binding the TexeBox Text property with the "Name" property in the ViewModel
Binding binding = new Binding("Name");
binding.Source = ViewModel;
binding.Mode = BindingMode.TwoWay;
SomeTextBox.SetBinding(TextBox.TextProperty, binding);