How to access the costom dependency property from the XAML
-
18 Nopember 2009 20:23
I would like to assign a value to the custom dependecy property (MyDP) of the window. But my following code got an error "Error 1 The property 'MyDP' was not found in type 'Window'. Anyone could point me the to right way. Thanks in advance.
<Window x:Class="Messenger.Demo.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" MyDP ="True"> <Grid> </Grid> </Window> public partial class Window1 : Window { public Window1() { InitializeComponent(); } public static readonly DependencyProperty MyDPProperty = DependencyProperty.RegisterAttached("MyDP", typeof(bool), typeof(Window1), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnMyDPChanged))); private static void OnMyDPChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { //Do something herer... } public bool MyDP { get { return (bool)GetValue(MyDPProperty); } set { SetValue(MyDPProperty, value); } } }
Semua Balasan
-
19 Nopember 2009 1:23
The reason you are not seeing your custom DP is because you defined your DP on the Window1 class but in XAML you are constructing an instance of the Window class and setting it's x:Class attribute to Window1.
If you want to see the DP correctly you can remove the x:Class attribute (make sure to do this first) and change the XAML to create an instance of the Window1 class, something like this<Window1 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" MyDP ="True"> <Grid> </Grid> </Window1>Make sure to add a proper namespace alias (xmlns:Foo).
Interestingly, if you don't remove the x:Class attribute first you will consistently crash Visual Studio (I assume a self referential stack overflow is occurring)
All that being said, I would NOT add a custom DP to your MainWindow like this. You typically want to add custom DP's to UserControls that are going to be used by your main Window.
Hopefully that helps- Disarankan sebagai Jawaban oleh Foovanadil 19 Nopember 2009 1:23
-
19 Nopember 2009 2:54Thanks Foovanadil for your answer. I am new to WPF, what do you mean by "Make sure to add a proper namespace alias (xmlns:Foo)."? For example, if my project name space is MyNameSpace, do you mean the following changes?
<local:Window1
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNameSpace"
Title="Window1" Height="300" Width="300" MyDP="True" >
<Grid>
</Grid>
</local:Window1> -
19 Nopember 2009 16:47Yes, excatly. xmlns stands for XML Namespace wha is placed after colon (:), which in your case is local, is considered the namespace alias. In order to reference your Window1 class you need to provide a namespace alias for the XAM parser to know where to look when constructing your class.
Did the change work for you? -
19 Nopember 2009 21:43
No It does not work. It returned the following error:
Error 1 The name 'InitializeComponent' does not exist in the current context C:\Dev\Test\Dot Net\WpfApplication5\WpfApplication5\Window1.xaml.cs 24 13 WpfApplication5
Error 2 The tag 'Window1' does not exist in XML namespace 'clr-namespace:WpfApplication5'. Line 2 Position 5. C:\Dev\Test\Dot Net\WpfApplication5\WpfApplication5\Window1.xaml 2 5 WpfApplication5
And following is the my testing source code:
<local:Window1 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication5" Title="Window1" Height="300" Width="300" MyDP ="True"> <Grid> </Grid> </local:Window1> namespace WpfApplication5 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } public static readonly DependencyProperty MyDPProperty = DependencyProperty.RegisterAttached("MyDP", typeof(bool), typeof(Window1), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnMyDPChanged))); private static void OnMyDPChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { //Do something herer... } public bool MyDP { get { return (bool)GetValue(MyDPProperty); } set { SetValue(MyDPProperty, value); } } } } -
19 Nopember 2009 22:30
Ahhh I am an idiot, sorry it was late last night and I didn't read your source code carefully enough.
Forget what I said in my previous post. I didn't realize you were registering an Attached property. For some reason I thought you were trying to register a normal DP.
Anyways, the problem is this:
When you register and Attached DP the Get and Set value calls are different then when you register a normal DP. For an attached property you need to provide a GetPropertyName static method and a SetPropertyName static method.
So if you change your code behind to be:
public static void GetMyDP(UIElement element, Boolean value) { ... } public static void SetMyDP(UIElement element, Boolean value) { ... }
And change your xaml back to what you had originally with one small modification (note how I am referencing that attached DP)
<Window x:Class="Messenger.Demo.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication5" Title="Window1" Height="300" Width="300" local:Window1.MyDP ="True"> <Grid> </Grid> </Window>
Then everything should work.
Sorry for the confusion -
19 Nopember 2009 22:53Thanks Foovanadil. I see your point and actually before asking this question I did try the Attached property (in the same way as your above code) and it did work perfectly. Then I asked myself: how to do that for a normal dependecy property (not the attached property)? I thought there could be a straightforward way that I have missed out.
-
19 Nopember 2009 23:10
Sorry, I did not realize it uses a different method to register a normal DP than the Attached property. Now I have changed the Register method in the following souce code - but I got the same error.
namespace WpfApplication5 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } public static readonly DependencyProperty MyDPProperty = DependencyProperty.Register ("MyDP", typeof(bool), typeof(Window1), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnMyDPChanged))); private static void OnMyDPChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { //Do something herer... } public bool MyDP { get { return (bool)GetValue(MyDPProperty); } set { SetValue(MyDPProperty, value); } } } }<Window x:Class="WpfApplication5.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication5" Title="Window1" Height="300" Width="300" MyDP="True"> <Grid> </Grid> </Window> -
20 Nopember 2009 2:26
I don't quite understand why you would need a regular dependency property in the code behind of Window1 like that.
Why not just put the value in the constructor of Window1? That is the same behavior as what you are trying to do. Setting a dependency property like you are trying to do (which I don't think is even possible) is the same as just setting the value in the code behind.
If you are doing an attached property then it would work like I explained above. You won't be able to use a regular dependency property in this situation and I don't why it would be needed.- Ditandai sebagai Jawaban oleh Roger NZ 22 Nopember 2009 21:34
-
22 Nopember 2009 21:34Thanks foovanadil. Good point. Actually I am not sure wheather what I was trying to do is a correct WPF way. This is my practice while learning the DP. It looks like that is not good practice to setting dependency propperty in my way.
I am from the Windows form background and while learning WPF, I feel the WPF is quite powerful and flexible. For example the DP is very cool stuff but where and how it should be used needs a learning curve to understand. -
14 April 2012 14:57
Foovanadil's answer is incorrect but was marked as the answer.
If you design custom controls using a UserControl OR you want to be able to use WPF binding support from the properties windows in the designer, you must have a DependencyProperty in the code behind. There is only 1 other way to do this when you create a custom control by overrriding the DefaultKeyStyle property.
http://www.wpftutorial.net/howtocreateacustomcontrol.html
So bottom line, if you want to use binding in WPF you must have a DP in the code-behind of the control's XAML, or there must be a DefaultKeyStyle registration for that control type.
JP Cowboy Coders Unite!