C# WPF Binding to variable and property in code behind - c#

I got an integer in my viewmodel and a string in my view that I need to show combined.
This is the code in the view:
Binding buttonBinding = new Binding() {
Path = new PropertyPath(nameof(ButtonViewModel.MyInteger)),
};
_button.SetBinding(Button.ContentProperty, buttonBinding);
Can I attach my string at some point or do I need to transfer it into the viewmodel and make the property a single string?

You could use the ContentStringFormat property to specify a StringFormat for the binding:
string s = "some string...";
Binding buttonBinding = new Binding()
{
Path = new PropertyPath(nameof(ButtonViewModel.MyInteger)),
};
_button.SetBinding(Button.ContentProperty, buttonBinding);
_button.ContentStringFormat = $"{{0}} {s}";

Related

WPF Binding to a value type

What binding path do I specify if I want WPF to bind to an int? Can I even do that?
TextBox textBox = new TextBox();
textBox.DataContext = myValueType;
textBox.SetBinding(TextBox.TextProperty, new Binding("what do I put here?");
If I clearly understand you, you can write something like this to bind int myValueType property to the textBox Text.
textBox.SetBinding( TextBox.TextProperty, new Binding( "DataContext" )
{ RelativeSource= new RelativeSource( RelativeSourceMode.Self ) } );
Yes you can with:
TextBox textBox = new TextBox();
textBox.DataContext = this;
textBox.SetBinding(TextBox.TextProperty, new Binding("myValueType"));
Here the DataContext variable is the object that contains myValueType property. If the property is declared in the same class you can use this.
If you don't want to set the DataContext of your TextBox, you can use:
textBox.SetBinding(TextBox.TextProperty, new Binding("myValueType") { Source = TheObjectThatContainsMyValueProperty });
If you are not forced to use the code behind then prefer the xaml code. It is eaiser to write and understand these stuff in xaml.

BindingInflate with different ViewModel

In my android view, I try to create a bunch of LinearLayouts using BindingInflate. It actually works fine, but I need to provide another ViewModel as DataContext. How do I achieve this?
In xaml I would just use
newLayout.DataContext = mySecondViewModel;
Following code is obviously not working, but something I would like to use:
var layout = this.BindingInflate(Resource.Layout.statistics_header, layoutContainer);
layout.BindingContext = mySecondViewModel
UPDATE:
Thanks for the comment - I did not know about the FrameControl. But unfortunatly I still could not figure out, how to use this.
What I want to achieve, is to fill up a viewpager with some fragments and a relative layout with corresponding headers. It would be easy to connect them to the same viewmodel.
Here is my current code:
var relativeLayout = FindViewById<RelativeLayout>(Resource.Id.statistics_header);
var layoutContainer = new MvxFrameControl(this, null)
{
LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent),
DataContext = statistic,
};
var layout = this.BindingInflate(Resource.Layout.statistics_header, layoutContainer);
relativeLayout.AddView(layoutContainer);
return new MvxPagerFragmentAdapter.FragmentInfo
{
FragmentType = typeof(StatisticsFragment),
Title = "StatisticsFrag",
ViewModel = statistic,
ConnectedView = layoutContainer
};
It fails that it's not possible to bind. But the DataContext is set to the right ViewModel where every property is set.
Am I missing a point?
Regarding to Stuarts comment I answer this for him:
I need to use a MvxFrameControl and can set the DataContext:
var layoutContainer = new MvxFrameControl(Resource.Layout.statistics_header, this, null)
{
LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent),
DataContext = statistic
};
layoutContainers.Add(layoutContainer);
return new MvxPagerFragmentAdapter.FragmentInfo
{
FragmentType = typeof(StatisticsFragment),
Title = "StatisticsFrag",
ViewModel = statistic,
ConnectedView = layoutContainer
};

Cell Style Binding does not Update on Value Change

I have a DataGrid which is bound to a Collection of Objects. Every DataGridColumn is created in code behind.
The Background of these columns is dependent on different values of the object. I create the background binding in the CellStyle (as it should not override default style's from triggers).
var backgroundBinding = new Binding
{
Converter = new MyBindingConverter(),
ConverterParameter = new MyConverterParameter()
};
cellStyle.Setters.Add(new Setter(Control.BackgroundProperty, backgroundBinding));
As you can see it binds directly to the element. As different value are changing the value of the Columns is updated accordingly, but the converter of the Binding is not called.
I tried calling OnPropertyChanged(null) to show that the object was updated, but sadly this does not work.
Did you try to specify Path for backgroundBinding? Something like:
var backgroundBinding = new Binding
{
Converter = new MyBindingConverter(),
ConverterParameter = new MyConverterParameter(),
ElementName = YourElementName,
Path = PropertyOnElement
};
cellStyle.Setters.Add(new Setter(Control.BackgroundProperty, backgroundBinding));

Is OneTime binding in code different from setting local value directly?

What is the difference between this OneTime binding:
//Create the source string
string s = "Hello";
//Create the binding description
Binding b = new Binding("");
b.Mode = BindingMode.OneTime;
b.Source = s;
//Attach the binding to the target
MyText.SetBinding(TextBlock.TextProperty, b);
And this?
MyText.Text = s;
Its very much different. By the second method you can change your bound value at any point of time in code. But with one time binding the bound value is evaluated only on app start or data context change.
See OneTime binding description here.

sending multi values to datagrid field Converter from codebehind

I am creating infragistics wpf grid at runtime.
in FieldLayoutInitialized i am creating unbound fields.
one sample unbound field is
UnboundField field = new UnboundField();
field.Name= "Testfield";
field.BindingPath = "Binding path";
FieldLayout fieldLayout;
fieldLayout.Fields.Add(field)
But my requirement is i have a field which is calculated one so for that i created converter. converter will return sum of two values.
A3 = A1+A2;
If it is from XAML file we can write like
<Textbox.Value>
<MultiBinding Converter="{StaticResource ConvertnameClass}" Mode="OneWay">
<Binding Path="A1"/>
<Binding Path="A2"/>
</MultiBinding>
</Textbox.Value>.
field.Converter = coverter class object;
field.ConverterParameter = ???;
if it is single binding we can send the
field.BindingPath = "class prop value";
how can i send multiple binding values to converter from code behind when it is creating run time.
please help me out.
here is a sample that creates a multibinding in code behind
put this at your FieldLayoutInitialized event
private void FieldLayoutInitialized(object sender, FieldLayoutInitializedEventArgs e) {
var fieldlayout = e.FieldLayout;
UnboundField field = new UnboundField();
field.Name = "Testfield";
fieldlayout.Fields.Add(field);
var multiBinding = new MultiBinding();
multiBinding.Mode = BindingMode.OneWay;
multiBinding.Converter = new MultiBindingConverter(); // implement IMultiValueConverter
multiBinding.Bindings.Add(new Binding() { Path = new PropertyPath("A1"), Mode = BindingMode.OneWay });
multiBinding.Bindings.Add(new Binding() { Path = new PropertyPath("A2"), Mode = BindingMode.OneWay });
field.Binding = multiBinding;
}
probably you must specify Source or RelativeSource for the two bindings
hope this helps (i used the 11.1 libs)

Categories