How to bind the BindingBase property to a variable in Xamarin - c#

I'm able to bind the property from entity to a listview content page element as below,
highlightGrid.SetBinding(IsVisibleProperty, "IsPaymentPlanEnding");
But I want to how do I bind this "IsPaymentPlanEnding" property value to a variable. Trying with the below code, but it is throwing a compilation error.
bool IsPaymentPlanEnding = BindingContext.GetBindingValue("IsPaymentPlanEnding");
Please let me know how do I bind the entity property value to variable.

You can store your binding in a variable like this:
BindingBase paymentPlanEndingBinding = new Binding("IsPaymentPlanEnding");
Then reference it when doing the actual binding:
highlightGrid.SetBinding(IsVisibleProperty, paymentPlanEndingBinding);
I wrote a simple unit test for that:
[Test]
public void BindingBase_test()
{
MockForms.Init();
BindingBase binding = new Binding("Value");
var pickerItem = new PickerSearchItem {Value = "the_value"};
var label = new Label {BindingContext = pickerItem};
label.SetBinding(Label.TextProperty, binding);
label.Text.ShouldBe("the_value");
}

Your BindingContext needs to Implement INotifyPropertyChanged.
And the BindingContext should hold a property (of type bool) called IsPaymentPlanEnding.
Then you can just leave the line as it is:
highlightGrid.SetBinding(IsVisibleProperty, "IsPaymentPlanEnding");
Learn about Bindings

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.

Is it possible to bind to a property using reflection in WPF?

I'm writing code to generate a bunch of textboxes attached to property. Is there any way you can set the source to a property found using reflection, stored as PropertyInfo?
Code for going through the properties:
foreach(PropertyInfo prop in GetType().GetProperties())
{
UI.Text ctrl = new UI.Text(prop.Name, prop.GetValue(this).ToString(), prop);
sp.Children.Add(ctrl);
}
(Note: UI.Text is a custom control that contains the TextBox, and sp is a StackPanel)
Binding code:
Binding bind = new Binding() { Source = prop };
if (prop.CanWrite)
{
TextBox.SetBinding(TextBox.TextProperty, bind);
}
else
{
TextBox.IsEnabled = false;
}
I currently get the error "Two-way binding requires Path or XPath" which usually occurs when trying to bind to a read-only property. Since the code is protected against that, it's obvious that simply binding to the PropertyInfo doesn't bind to the property itself.
Set the Path property of the Binding to prop.Name and the Source property to this or whatever object that you want to bind to:
Binding bind = new Binding() { Path = new PropertyPath(prop.Name), Source = this };
if (prop.CanWrite)
{
TextBox.SetBinding(TextBox.TextProperty, bind);
}
else
{
TextBox.IsEnabled = false;
}
The Path of a Binding specifies the property to bind to and the Source property specifies the object in which this property is defined.

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);

Control not updating when binding data source changes?

Sorry if this has been asked but I can't find it.
I'm trying to bind a textbox to a datasource, but the textbox isn't updating when the datasource changes... Here's my code, can anyone suggest what I'm doing wrong?
Thanks!
public Controller()
{
myForm.databaseTextBinding = new Binding("Text", ac, "connString");
myForm.databaseTextBinding.ControlUpdateMode = ControlUpdateMode.OnPropertyChanged;
myForm.setupSources();
}
public partial class Form1 : Form
{
public Binding databaseTextBinding;
public void setupSources()
{
DatabaseTextBox.DataBindings.Add(databaseTextBinding);
}
}
UPDATE:
I can now make textboxes that will update. I have a new problem though. The datasource itself changes by me making a new ac object. But if I do that, the binding now longer updates. I've considered that maybe the property isn't changing but I'm sure that it is!
Eg this works
ac.cString = "ABC";
ac.cString = "DEF";
but this doesn't...
ac = new AccessConnector(path);
ac.cString = "ABC";
ac.cString = "DEF";
Does the type of the bound object (i.e. ac) implement INotifyPropertyChanged? if so, does the property "connString" raise a PropertyChanged event when it's changed?
if not, you may have a look at the INotifyPropertyChanged sample
EDIT:
the part does not work is due to you did not change your binding to the new object - it's still bound to the old object. when you assign a new object to the reference variable ac, the binding to the original object won't change - thus it still points to the previous object.
Presuming that your Binding is binding a BindingSource to the textbox, you need to add a BindingSource.ResetBindings() to your code.

Attaching DataTriggers at runtime

Is it possible to attach datatriggers to a style at runtime? I've been through my (non-working) code a few times now and can't seem to find where I've gone wrong.
Here's the method I use to attach the style and trigger:
private void AttachVisibilityTrigger(Control ctrl)
{
Style stl = new System.Windows.Style();
DataTrigger dt = new DataTrigger();
PropertyInfo pi = _entity.GetType().GetProperty(this.SecondaryOptions[ctrl.Name]);
Type controlType = this.GetControlTypeForProperty(ref dt, pi); //gets the control type based on the property name and then sets the value for the DataTrigger for which I want the visibility to be hidden
Binding b = this.GetVisibilityBindingByControlType(controlType); //returns a new Binding with the appropriate Path set that corresponds to the bound property value (e.g IsChecked for CheckBoxes, Text for TextBoxes, SelectedValue for Comboboxes, etc)
b.ElementName = this.SecondaryOptions[ctrl.Name];
dt.Binding = b;
dt.Setters.Add(new Setter(Control.VisibilityProperty, System.Windows.Visibility.Hidden));
stl.Triggers.Add(dt);
ctrl.Style = stl;
}
I'm pretty sure the binding is just broken, i created similar styles in code and they work.
Especially this line looks quite suspicious:
b.ElementName = this.SecondaryOptions[ctrl.Name];
(If you want to bind to the control itself use RelativeSource instead.)
Have you checked the Output window of VisualStudio for binding errors?

Categories

Resources