Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XAML: How can I bind a DependencyProperty to a C# property of the same name on a different object?

Using:

  • Visual Studio Community Edition 2015
  • .Net 4.0

I've implemented this answer, producing my own CheckBox class complete with an IsChecked DependencyProperty. That property is backed by the IsChecked property on the WPF CheckBox, or would be if it would work. Working would mean my getter and setter are called when the checkbox is toggled.

If I rename my property to IsChecked_temp and modify the XAML to match, it works fine. I think this is a naming conflict, but why doesn't ElementName resolve it? My minimal test case follows.

EDIT 0: I forgot to mention, I get no errors or warnings.

EDIT 1: This answer was initially accepted because it works for the test case, but it's apparently not the entire answer. Applying it to my project (and renaming the CheckBox class to ToggleBox) yields a XamlParseException at every use of the property:

A 'Binding' cannot be set on the 'IsChecked' property of type 'ToggleBox'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

I'll try to get a minimal test case going to show this.

CheckBox.xaml

<UserControl x:Class="CheckBox_test.CheckBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Name="Self">
    <StackPanel>
        <CheckBox IsChecked="{Binding IsChecked, ElementName=Self}" />
    </StackPanel>
</UserControl>

CheckBox.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace CheckBox_test
{
    public partial class CheckBox : UserControl
    {
        public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register(
             "IsChecked",
             typeof(bool),
             typeof(CheckBox),
             new FrameworkPropertyMetadata(false,
                     FrameworkPropertyMetadataOptions.AffectsRender));

        public bool IsChecked
        {
            get { return (bool)GetValue(IsCheckedProperty); }
            set { SetValue(IsCheckedProperty, value); }
        }

        public CheckBox()
        {
            InitializeComponent();
        }
    }
}

MainWindow.xaml

<Window x:Class="CheckBox_test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CheckBox_test">
    <Grid>
        <local:CheckBox />
    </Grid>
</Window>

MainWindow.xaml.cs (for completeness)

using System.Windows;

namespace CheckBox_test
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}
like image 838
Grault Avatar asked Oct 29 '15 20:10

Grault


1 Answers

Very interesting question (at least for me) so it turns out that there is really a conflict of names when you register your Dependency Property.

I'm not exactly sure if this is an answer but I think you'll find this interesting if you didn't knew or thought about it before.

I've used "CheckBox.IsChecked", but any unique name would suffice probably.

public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register(
         "CheckBox.IsChecked",
         typeof(bool),
         typeof(CheckBox),
         new FrameworkPropertyMetadata(false,
                 FrameworkPropertyMetadataOptions.AffectsRender));

This works without change in the name of your property

public bool IsChecked
{
    get
    {
        return (bool)GetValue(IsCheckedProperty);
    }
    set
    {
        SetValue(IsCheckedProperty, value);
    }
}

When you create names for your dependency properties, you must choose unique names that are not being used for dependency properties or events in any base classes that you inherit from; otherwise, an ArgumentException is thrown during runtime. For more information about dependency properties and activity binding, see Custom Activity Binding Sample and Simple Activity Sample.

https://msdn.microsoft.com/en-us/library/vstudio/ms734499(v=vs.90).aspx

Yet another reminder how big of a noob I am :)

like image 180
kirotab Avatar answered Sep 29 '22 14:09

kirotab