0

I want to define a DependencyProeprty in my Window class like following code.

namespace dgCommon
{

    //MenuPage is a Page.
    public partial class MenuPage : IFrameInterop
    {

        public Style MenuIconStyle { get { return (Style)GetValue(MenuIconStyleProperty); } set { SetValue(MenuIconStyleProperty, value); } }
        public static readonly DependencyProperty MenuIconStyleProperty = DependencyProperty.Register("MenuIconStyle", typeof(Style), typeof(MenuPage), new UIPropertyMetadata(null));
    ...

In Custom control, this code enable a dependency proeprty. But in a page, following XAML dosen't compile.

<Page x:Class="dgCommon.MenuPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:dgCommon="clr-namespace:dgCommon" 

      <!--following line is problem.-->
      MenuIconStyle="{StaticResource MenuButtonStyle}"

      x:Name="pageMenu">
...

What is a reason?

H.B.
  • 166,899
  • 29
  • 327
  • 400
mjk6026
  • 1,484
  • 3
  • 20
  • 38

3 Answers3

2

You can't use assign the dependency property in the XAML of the control/window/page that declares it. If you want to set its default value, do it in code-behind.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • There also seems to be a problem with the code behind as MenuPage does only appear to inherit from an interface... – H.B. Sep 03 '11 at 12:27
  • 1
    @H.B., the fact it inherits from Page is already specified in XAML (and a partial class definition is generated from the XAML). You don't need to specify the base type in every partial definition of the class – Thomas Levesque Sep 03 '11 at 12:31
  • Of course you can use a DP in the XAML of the control that declares it, you just can't set it in XAML. If we couldn't use a DP in the XAML it would be plain useless. – Louis Kottmann Sep 03 '11 at 12:35
  • 1
    @Baboon, yes, you can use it e.g. in a binding, because it's not statically referenced (i.e. not checked by the compiler), but you can't assign it; that's what I meant. And no, it's not useless: you can assign the property where you use the view, just not where you define it. Anyway, I don't think it deserved a downvote... – Thomas Levesque Sep 03 '11 at 12:39
  • Alright you can use it as some kind of tag only, but in his scenario, it's used to expose a property within the window to other parts of the program. The misleading and short answer desserved a downvote in my opinion. – Louis Kottmann Sep 03 '11 at 12:52
1

This question has been answered here: Setting a custom property within a WPF/Silverlight page
The reason for this problem is also explained in the link.

You have a few options to assign your custom Dependency Property in Xaml

Option 1. Create a base class for Page where you add your DP

MenuPage.xaml

<dgCommon:MenuPageBase x:Class="dgCommon.MenuPage" 
                       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                       xmlns:dgCommon="clr-namespace:dgCommon"
                       MenuIconStyle="{StaticResource MenuButtonStyle}">
    <!--...-->
</dgCommon:MenuPageBase>

MenuPage.xaml.cs

public partial class MenuPage : MenuPageBase
{
    // ...
}

MenuPageBase.cs

public class MenuPageBase : Page
{
    public static readonly DependencyProperty MenuIconStyleProperty =
        DependencyProperty.Register("MenuIconStyle",
                                    typeof(Style),
                                    typeof(MenuPage),
                                    new UIPropertyMetadata(null));
    public Style MenuIconStyle
    {
        get { return (Style)GetValue(MenuIconStyleProperty); }
        set { SetValue(MenuIconStyleProperty, value); }
    }
}

Option 2. Implement static get and set methods for MenuIconStyle

MenuPage.xaml

<Page x:Class="dgCommon.MenuPage" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:dgCommon="clr-namespace:dgCommon"
      dgCommon.MenuPage.MenuIconStyle="{StaticResource MenuButtonStyle}">

MenuPage.xaml.cs

public partial class MenuPage : Page
{
    public static readonly DependencyProperty MenuIconStyleProperty =
        DependencyProperty.Register("MenuIconStyle",
                                    typeof(Style),
                                    typeof(MenuPage),
                                    new UIPropertyMetadata(null));
    public Style MenuIconStyle
    {
        get { return (Style)GetValue(MenuIconStyleProperty); }
        set { SetValue(MenuIconStyleProperty, value); }
    }
    public static void SetMenuIconStyle(Page element, Style value)
    {
        element.SetValue(MenuIconStyleProperty, value);
    }
    public static Style GetMenuIconStyle(Page element)
    {
        return (Style)element.GetValue(MenuIconStyleProperty);
    }
    // ...
}

Option 3. Use Attached Properties as other people have pointed out.

Community
  • 1
  • 1
Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266
0

As said by Thomas, to give a default value to a DP in code-behind of a window, replace

new UIPropertyMetadata(null) with new UIPropertyMetadata(DEFAULT_VALUE_HERE)

That said, a DP is pretty useless if you don't refer to it in your view, you can access this DP in the xaml by first giving a name to your control:

<Page x:Class="dgCommon.MenuPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:dgCommon="clr-namespace:dgCommon" 
      x:Name="pageMenu" />

Then calling the DP like this:

<Page x:Class="dgCommon.MenuPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:dgCommon="clr-namespace:dgCommon" 
      x:Name="pageMenu" Style="{Binding MenuIconStyle, ElementName=pageMenu}" />

Now if you really want to have a Property on Window that is called MenuIconStyle, you will have to look into attached properties

Louis Kottmann
  • 16,268
  • 4
  • 64
  • 88