I have previously used the following code I found somewhere to implement a BindingProxy in WPF.
public class BindingProxy : Freezable
{
public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return this.GetValue(DataProperty); }
set { this.SetValue(DataProperty, value); }
}
}
I have tried to create a similar class for my Xamarin application which looks like this.
public class BindingProxy : BindableObject
{
// Using a DependencyProperty as the backing store for Data.
// This enables animation, styling, binding, etc...
public static readonly BindableProperty DataProperty = BindableProperty.Create(nameof(Data), typeof(object), typeof(BindingProxy), null);
public object Data
{
get { return this.GetValue(DataProperty); }
set { this.SetValue(DataProperty, value); }
}
}
This is the closest I could come up with to the Freezable class in Xamarin, unfortunately however when I declare my xaml as so
<ContentPage.Resources>
<binding:BindingProxy x:Key="BindingProxy" Data="{Binding BindingContext}" />
</ContentPage.Resources>
the Data property is never set to the BindingContext (or any other value) and returns the default value (null).
Can anyone provide any insight to what I might be doing wrong?
According to the answers here resources are not provided with the BindingContext and therefore do not support databinding.
Depending on your use case there might be another option to get the specific BindingContext, so you maybe want to explain that a little.
Related
The propertychanged trigger in a viewmodel of a UWP app with Template10 is triggered by by the following way:
public var Thing{ get { return thing; } set { Set(ref thing, value); } }
The Set function is placed in the class bindableBase.
How can I use this same function in a Usercontrol?
I tried the folowing, but that didn't work:
BindableBase x;
var foo;
public var Foo{ get { return foo; } set { x.Set(ref foo, value); } }
you don't use in that fashion you use with a viewmodel for example if the Page you place the usercontrol would have a property associated with populating the fields of the usercontrol part of the viewmodel that is bound to the DataContext of the Page. I think you need to review MVVM. Or the viewmodel could be the DataContext of the userControl in question.
When creating a UserControl you'll want to use a DependencyProperty to create bindable properties. It's required to make them behave as expected when using the UserControl inside of an other control (like a Page). DependencyProperties are defined like this:
public int MyProperty
{
get { return (int)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new PropertyMetadata(0));
They're most easily created using the propdp snippet in Visual Studio.
I recommend giving this MVA course a look (especially the first lesson) on how to create custom controls
Is it possible to add my own custom property to any control?
I want to do something similar to e.g. x:Name="aname".
So I could write in xaml:
<TextBox local:MyCustomProperty="myValue" />
Maybe someone can provide a small sample or a link showing how to do this.
In google I only find markup extensions, which doesn't seem to be what I am looking for.
You can use an Attached Property.
public class MyCustomProperty
{
#region Color dependency property
public static readonly DependencyProperty ColorProperty;
public static Color GetColor(DependencyObject obj)
{
return (Color)obj.GetValue(ColorProperty);
}
public static void SetColor(DependencyObject obj, Color value)
{
obj.SetValue(ColorProperty, value);
}
#endregion
static MyCustomProperty()
{
//register attached dependency property
var metadata = new FrameworkPropertyMetadata(Colors.Transparent);
ColorProperty = DependencyProperty.RegisterAttached("Color",
typeof(Color),
typeof(MyCustomProperty), metadata);
}
}
And in XAML
<DockPanel custom:MyCustomProperty.Color="{StaticResource MyColor}" >
I have the following class schema
public Class Test : DependencyObject
{
private DependencyProperty _thickness = DependencyProperty.Register("Thickness", typeof(double), typeof(CounterDataStreamWrapper));
public double Thickness
{
get
{
return (double)GetValue(this._thickness);
}
set
{
SetValue(this._thickness, value);
}
}
... Rest of the code
}
Essentially I have a collection of Test objects, and I want to bind the Thickness value for each one to its corresponding UI element. I am not too familiar with C# binding. When I try to create multiple objects, I am running into "DependencyProperty is already registered" issue. I am sure that I am just missing some key concept for binding to DependencyProperty.
Any help is appreciated!
You are registering the Thickness DependencyProperty on the CounterDataStreamWrapper type and private per instance.
Make the DependencyProperty public static and register it for the class Test.
public static DependencyProperty Thickness =
DependencyProperty.Register("Thickness", typeof(double), typeof(Test));
It's supposed to be static. Like this:
private static DependencyProperty _thickness ...
Can someone help me with this question?) In My XAML I have Listbox element. I want to add my user property into it(in my case - ConnectorStyle)
My XAML code:
<ListBox ItemsSource="{Binding Nodes}" ItemsPanel="{StaticResource CanvasItemsPanelTemplate}"
ItemTemplate="{StaticResource NodePictureTemplate}"
ItemContainerStyle="{StaticResource CanvasItemStyle}"
ConnectorStyle="{StaticResource ConnectorLineStyle}"/>
In my Model I have prepared this property:
public partial class MainPage : UserControl
{
public static readonly DependencyProperty ConnectorStyleProperty = DependencyProperty.Register(
"ConnectorStyle", typeof(Style), typeof(NodePicture), null);
public MainPage()
{
InitializeComponent();
}
public Style ConnectorStyle
{
get { return (Style)GetValue(ConnectorStyleProperty); }
set { SetValue(ConnectorStyleProperty, value); }
}
}
But I is a mistake - Cannot resolve ConnectorStyle.
Is there a simple (or a right way ) way of doing this?
There are two ways to do this: Either you can write a subclass for the ListBox that adds the DependencyProperty or you can write an attached property.
In your case you probably want to write a subclass that adds the property. Try something like this:
public class MyListBox : ListBox
{
public static readonly DependencyProperty ConnectorStyleProperty = DependencyProperty.Register(
"ConnectorStyle", typeof(Style), typeof(MyListBox), null);
public Style ConnectorStyle
{
get { return (Style)GetValue(ConnectorStyleProperty); }
set { SetValue(ConnectorStyleProperty, value); }
}
}
This will add a new type of ListBox that you can add in your xaml code. It will have all the same properties as a regular ListBox, but it will also have the ConnectorStyle property.
If you need to respond to changes to the ConnectorStyle property in your listbox then you should change the code for the Dependency Property, but that is outside the scope of this question.
And in XAML it shoul be :
<local:ListBoxEx
ConnectorStyle="{StaticResource ConnectorLineStyle}"/>
I have a custom MarkupExtension that simulates binding. It works well in normal assignments but not when used in Style Setters, for example:
<Setter Property="Content" Value="{local:MyExtension}" />
results in a XamlParseException:
A 'Binding' cannot be set on the 'Value' property of type 'Setter'.
A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
This is implementation of the extension:
public class MyExtension : MarkupExtension
{
public MyExtension()
{
Value = 123;
}
public object Value
{
get;
set;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var binding = new Binding("Value")
{
Source = this,
};
return binding.ProvideValue(serviceProvider);
}
}
What's the problem?!
Kind of guessing, but it's likely because the XAML compiler has special built-in support for the Binding class, allowing its usage in this scenario (and others). The Binding class is also a MarkupExtension, but unfortunately it seals its implementation of ProvideValue().
That said, you might just get away with this:
public class MyBinding : Binding
{
private object value;
public object Value
{
get { return this.value; }
set
{
this.value = value;
this.Source = value;
}
}
}
Since ProvideValue will return the Binding instance anyway.
From the documentation, it looks like the object must be freezable (so they can be shared between various interested parties)
http://msdn.microsoft.com/en-us/library/system.windows.setter.value.aspx
"Data binding and dynamic resources within the object is supported if the specified value is a Freezable object. See Binding Markup Extension and DynamicResource Markup Extension."
why don't you
return Value
inside the ProvideValue??
else
You can bind to only DependencyProperty. make a dependency property for Value in your MyExtension Class!
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(Object), typeof(MyContentControl), new UIPropertyMetadata());