Search code examples
c#wpf.net-4.5dependency-properties

Create dependency property for WPF Window itself in its code behind xaml.cs


I have a WPF window which I have changed its borders, title bar and buttons for a custom one. Separately in a ResourceDictionary I have defined the Style that I want to apply to my WPF window. Then I bind that style to my WPF Window using below line of code:

Style="{DynamicResource CustomWindowStyle}" 

Please see all my code posted in another thread that I created to ask for other things. Refer to this thread to see the code (I want to avoid repeating here again).

Now what I am trying to do is to create some custom properties (MyCustomProperty01, MyCustomProperty02) to that WPF Window, some like below:

myDialogView.xaml:

<Window x:Class="myApp.Views.myDialogView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:v="clr-namespace:myApp.Views"
        xmlns:vm="clr-namespace:myApp.ViewModels"
        mc:Ignorable="d" 
        d:DesignHeight="450" d:DesignWidth="800"
        ResizeMode="NoResize"
        SizeToContent="WidthAndHeight"
        Style="{StaticResource CustomWindowStyle}" 
        WindowStyle="None"

        MyCustomProperty01 = "true"
        MyCustomProperty02 = "true">

...and then in the code-behind of this WPF window (xaml.cs) I want to define those dependency properties MyCustomProperty01 and MyCustomProperty02, the ones you see above in the code snippet for the Window.

So I create those dependency properties in the code-behind as below.

myDialogView.xaml.cs (code-behind):

namespace myApp.Views
{
    public partial class myDialogView: Window
    {
        public myDialogView()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty MyCustomProperty01Property =
            DependencyProperty.Register("MyCustomProperty01",
                                        typeof(bool),
                                        typeof(myDialogView),
                                        new FrameworkPropertyMetadata(false));

        public bool MyCustomProperty01
        {
            get => (bool)GetValue(MyCustomProperty01Property );
            set => SetValue(MyCustomProperty01Property , value);
        }

        public static readonly DependencyProperty MyCustomProperty02Property =
            DependencyProperty.Register("MyCustomProperty02",
                                        typeof(bool),
                                        typeof(myDialogView),
                                        new FrameworkPropertyMetadata(false));

        public bool MyCustomProperty02
        {
            get => (bool)GetValue(MyCustomProperty02Property );
            set => SetValue(MyCustomProperty02Property , value);
        }
    }
}

So when I start typing these dependency properties MyCustomProperty01 and MyCustomProperty01 for the window in the xaml view, intellisense looks like it is not recognizing those dependency properties. So what am I doing wrong? Could some tell me how I can achieve this with some code snippet?


Solution

  • You need to registerattached for this to work.

    I'm not 100% sure why, I just know it won't work with the usual dependency property.

    I think it's because it's in a window tag and it's "really" a myDialogView causes the issue.

    Here's an example attached property I have:

        public static readonly DependencyProperty TakeMapPictureProperty = 
                DependencyProperty.RegisterAttached(
                "TakeMapPicture",
                typeof(bool),
                typeof(MainWindow),
                new FrameworkPropertyMetadata(false
              , new PropertyChangedCallback(TakeMapPictureChanged)
            ));
    
        private static async void TakeMapPictureChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }
    
        public static void SetTakeMapPicture(UIElement element, bool value)
        {
            element.SetValue(TakeMapPictureProperty, value);
        }
        public static bool GetTakeMapPicture(UIElement element)
        {
            return (bool)element.GetValue(TakeMapPictureProperty);
        }
    

    And in the window tag

        local:MainWindow.TakeMapPicture="{Binding CaptureMap}"
    

    Where you might want to use the one dependency property in several user controls or windows, you can define the attached properties in a separate class. There are a couple of ways to do this but the one I prefer looks like:

    public class MainWin : DependencyObject
    {
        public static readonly DependencyProperty MapFileProperty = DependencyProperty.RegisterAttached(
            "MapFile",
             typeof(string),
             typeof(MainWin),
             new FrameworkPropertyMetadata(string.Empty
                 , new PropertyChangedCallback(MapFileChanged)
            ));
    

    And that is used inside a window tag:

        local:MainWin.MapFile="{Binding Path=MapFile}"