MyControl.xaml.cs
public string achName
{
get { return (string)this.GetValue(achNameProperty); }
set { this.SetValue(achNameProperty, value); }
}
public static readonly DependencyProperty achNameProperty = DependencyProperty.Register("achName", typeof(string), typeof(MyControl), new PropertyMetadata(null));
MainPage.xaml
<My:MyControl achName="{Binding Name}"/>
name has a value, but it doesn't seem to get send to the dependendcy (achName) property. How can I fix this?
ViewModel
public string Name { get { return "some random test value"; } }
other bindings to viewmodel do work, so the problem doesn't lie there.
The only reason i can see is that Binding to Name is failing. You can debug your bindings to see if its not failing. Refer to this - Debug Data Bindings
Related
I have a control where i want to add CharacterCasing since it doesn't support it by default.
I added a custom dependency property called "CharacterCasing".
Now when i use it in xaml i want to have the options just like in the normal TextBox:
Any ideas how to implement the suggestion list in the dependency property?
This is my code in xaml:
<TestControl:APTextBox CharacterCasing="UpperCase" Text="{Binding AktuelleZeile.LKR, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}">
And this is the dependency property:
public static readonly DependencyProperty CharacterCasingProperty =
DependencyProperty.Register(name: "CharacterCasing",
propertyType: typeof(string),
ownerType: typeof(APTextBox),
typeMetadata: new PropertyMetadata("Normal"));
public string CharacterCasing
{
get { return (string)this.GetValue(CharacterCasingProperty); }
set { this.SetValue(CharacterCasingProperty, value); }
}
Because you define it as string. Change the string with CharacterCasing or which kind of enum you want to use.
public static readonly DependencyProperty CharacterCasingProperty =
DependencyProperty.Register(name: "CharacterCasing",
propertyType: typeof(CharacterCasing),
ownerType: typeof(APTextBox),
typeMetadata: new PropertyMetadata(CharacterCasing.Normal));
public CharacterCasing CharacterCasing
{
get { return (CharacterCasing)this.GetValue(CharacterCasingProperty); }
set { this.SetValue(CharacterCasingProperty, value); }
}
I have a UserControl with 2 custom DependencyPropertys (ColumnsCount, RowsCount):
public partial class CabinetGrid : UserControl
{
public static readonly DependencyProperty ColumnsCountProperty =
DependencyProperty.Register("ColumnsCount", typeof (int), typeof (CabinetGrid));
public static readonly DependencyProperty RowsCountProperty =
DependencyProperty.Register("RowsCount", typeof (int), typeof (CabinetGrid));
public int ColumnsCount
{
get { return (int) GetValue(ColumnsCountProperty); }
set { SetValue(ColumnsCountProperty, value); }
}
public int RowsCount
{
get { return (int) GetValue(RowsCountProperty); }
set { SetValue(RowsCountProperty, value); }
}
}
And here's the DataBinding:
<view:CabinetGrid Grid.Column="1" Grid.Row="2" x:Name="GridRack" ColumnsCount="{Binding SelectedRoom.ColumnCount}" />
whereas the window's DataContext has a property SelectedRoom which invokes PropertyChanged-Event.
Thru debugging, I got to know that the DataContext of the UserControl is set properly.
However, when SelectedRoom has changed (=> I selected another item in a list), the DependencyProperty ColumnsCount of my UserControl is not updated.
I am very frustrated, as I already spent an entire day debugging through this unexpected shit, using tools like XAMLSpy and WpfSpoon.
Please, help.
EDIT:
Clemens already pointed out, that a breakpoint in the CLR-Property wrapping the DependencyProperty (ColumnsCount) is not fired. This is a major issue, since I have to call some methods on the change. I'm trying to use the PropertyChangedCallback, but am currently experiencing some errors.
In order to get notified about value changes of a dependency property, you should specify a PropertyChangedCallback in the PropertyMetadata when you register the property.
public static readonly DependencyProperty ColumnsCountProperty =
DependencyProperty.Register(
"ColumnsCount", typeof(int), typeof(CabinetGrid),
new PropertyMetadata(OnColumnsCountPropertyChanged));
private static void OnColumnsCountPropertyChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var cabinetGrid = (CabinetGrid)obj;
// do something with the CabinetGrid instance
}
I have a property on my ViewModel that I need bound to a BindableProperty in my behaviour but I cant seem to get it to bind.
private int _test;
public int Test {
get {
return _test;
}
set {
if (SetProperty (ref _test, value)) {
_profileIsDirty = true;
NotifyPropertyChanged ("AllowUpdate");
}
}
}
Here is the property in the behaviour
public static readonly BindableProperty MinLengthProperty = BindableProperty.Create("MinLength", typeof(int), typeof(MinLengthValidator), 0);
public int MinLength
{
get { return (int)GetValue(MinLengthProperty); }
set { SetValue(MinLengthProperty, value); }
}
This is the property on the ViewModel and this is how I am trying to bind to it in XAML
<behave:TelephoneNumberValidatorBehaviour x:Name="phoneValidator" MinLength="{Binding Test, Mode=OneWay}"/>
But it never binds. Am I doing something wrong here?
Have you tried to change the value of your NotifyPropertyChanged to "Test" instead of "AllowUpdate"? Otherwise the UI is never notified that the value has changed of Test. Instead it raises that the value the AllowUpdate property has changed, which does not exist in your ViewModel.
The third parameter of BindableProperty.Create should be type of the class where the BindableProperty is defined. Based on your sample, I guess it should be typeof(TelephoneNumberValidatorBehaviour) and not typeof(MinLengthValidator)
I am new to binding. I have binded slider value to my control's property and my controls property get changed when I change the slider value.
Now, when I need to change the slider value by changing my property value, it does not work..
I modified the xaml from some internet source, but still not get the expected output.
can anyone help me out...
<Grid>
<cc:MyControl Name="mycntrl" ZoomPercentage="{Binding ElementName=slider,Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></cc:MyControl>
<Slider Name="slider" Margin="20,20,20,400" Minimum="100" Maximum="400"></Slider>
</Grid>
Updated:
My code behind for my ZoomPercentage dependency property is below
public double ZoomPercentage
{
get
{
return (double)GetValue(ZoomPercentageProperty);
}
set
{
SetValue(ZoomPercentageProperty, value);
}
}
My dependency registration
public static readonly DependencyProperty ZoomPercentageProperty = DependencyProperty.Register("ZoomPercentage", typeof(double), typeof(MyControl), new FrameworkPropertyMetadata(ZoomPercentagePropertyChanged));
public static void ZoomPercentagePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (args.OldValue != null)
{
if ((double)args.NewValue != (double)args.OldValue)
{
MyControl mycontrol = obj as MyControl;
mycontrol .ZoomTo((int)((double)args.NewValue));
}
}
}
Your ZoomPercentage property should be implemented as a Dependencyproperty
Something like this
public class MyControl:UserControl
{
public MyControl() : base() { }
public double ZoomPercentage
{
get { return (double)this.GetValue(ZoomPercentageProperty); }
set { this.SetValue(ZoomPercentageProperty, value); }
}
public static readonly DependencyProperty ZoomPercentageProperty = DependencyProperty.Register(
"ZoomPercentage", typeof(double), typeof(MyControl:),new PropertyMetadata(0));
}
read more here
If you want a data bound control in the UI to update after changes made in code then you have to do one of two things. One option is to correctly implement the INotifyPropertyChanged interface in the class that you declared your Value property.
The other is to declare your Value property as a DependencyProperty, although you should only really do this in the code behind of your Window or UserControl and opt for the first method if you are using a view model. The purpose of these two methods is for you to 'plug in' to WPF notification framework, so that your UI control will update. Please read the linked pages for more information.
I am having trouble setting my ContentProperty to "Text". The error I am given is:
Invalid ContentPropertyAttribute on type 'MyType', property 'Text' not found.
The code behind looks like this:
[ContentProperty("Text")]
public partial class MyType: UserControl
{
public MyType()
{
InitializeComponent();
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text",
typeof (string),
typeof(MyType)));
public static string GetText(DependencyObject d)
{
return (string) d.GetValue(TextProperty);
}
public static void SetText(DependencyObject d, string value)
{
d.SetValue(TextProperty, value);
}
public string Text
{
get
{
return (string)GetValue(TextProperty);
}
set
{
SetValue(TextProperty, value);
}
}
}
I have actually got it to work if I name the CLR property something other than the DependencyProperty - am I using DependencyProperties incorrectly?
I thought it would be because typeof(LinkText) should be typeof(MyType), but I was able to get my test project to compile. Could you post the XAML file which is causing the error?
EDIT: Followup
Your problem is the two static methods you have in your code sample. Try removing those, and it should compile and work. The static methods only work with Attached Properties, not Dependency Properties.
The error is coming from you're default value, set in:
... new PropertyMetadata(false) ...
Because the TextProperty is of type string, it expects a string for the default value. Try:
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
"Text",
typeof (string),
typeof(MyType),
new PropertyMetadata(String.Empty));