XAML: как привязать DependencyProperty к свойству C # с тем же именем на другом объекте?

С использованием:

  • Visual Studio Community Edition 2015
  • .Net 4.0

Я реализовал этот ответ, создав свой собственный CheckBox класс с IsChecked DependencyProperty. Это свойство поддерживается свойством IsChecked в WPF CheckBox или будет, если оно будет работать. Работа будет означать, что мои методы получения и установки вызываются при переключении флажка.

Если я переименую свое свойство в IsChecked_temp и изменю XAML для соответствия, он будет работать нормально. Я думаю, что это конфликт имен, но почему ElementName его не разрешает? Далее следует мой минимальный тестовый пример.

РЕДАКТИРОВАТЬ 0: я забыл упомянуть, у меня нет ошибок или предупреждений.

РЕДАКТИРОВАТЬ 1: Этот ответ был первоначально принят, потому что он работает для тестового примера, но, по-видимому, это не полный ответ. Применение его к моему проекту (и переименование класса CheckBox в ToggleBox) дает XamlParseException при каждом использовании свойства:

«Привязка» не может быть установлена ​​для свойства «IsChecked» типа «ToggleBox». «Привязка» может быть установлена ​​только для DependencyProperty объекта DependencyObject.

Я попытаюсь получить минимальный тестовый пример, чтобы показать это.

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 (для полноты)

using System.Windows;

namespace CheckBox_test
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

person Grault    schedule 29.10.2015    source источник
comment
Просто для проверки попробуйте написать IsChecked = {Binding Path = IsChecked, ElementName = Self}   -  person Spawn    schedule 29.10.2015
comment
@Spawn Я пробовал это с _temp и без него и получил те же результаты. Тем не менее, стоит попробовать, так что спасибо.   -  person Grault    schedule 30.10.2015
comment
Хорошо, завтра попробую ... Self - не такое уж редкое имя для UserControl, так что оно должно работать. Можете ли вы сказать, какую версию Visual Studio и .NET вы используете?   -  person Spawn    schedule 30.10.2015
comment
Я отредактировал эти детали в вопросе.   -  person Grault    schedule 30.10.2015
comment
О, и я получаю такое же (отсутствие) поведения в .Net 4.5.2.   -  person Grault    schedule 30.10.2015
comment
Я не понимаю, какой в ​​этом толк. Если вы хотите, чтобы CheckBox использовал CheckBox, а не UserControl ....... Вам не следует изобретать колесо.   -  person Federico Berasategui    schedule 30.10.2015
comment
Он просто оборачивает флажок (или любой элемент управления) в более сложный элемент управления, который упрощен для иллюстрации :)   -  person kirotab    schedule 30.10.2015
comment
@kirotab звучит довольно плохо, ИМО. Люди объединяют использование UserControl и настраиваемого элемента управления, которые представляют собой две совершенно разные концепции, предназначенные для разных случаев использования.   -  person Federico Berasategui    schedule 30.10.2015
comment
@HighCore Должен признаться, что я один из тех людей, о которых вы говорите. Так что спасибо, что напомнили мне, что существует такая вещь, как CustomControl. Определенно то, что мне нужно было сделать раньше, но завтра я постараюсь немного расширить свои знания в этой области.   -  person kirotab    schedule 30.10.2015
comment
То же. Я помню, как давно столкнулся с CutomControl и не понял, почему он существует. Однако это не имеет отношения к вопросу.   -  person Grault    schedule 30.10.2015


Ответы (1)


Очень интересный вопрос (по крайней мере, для меня), поэтому оказывается, что действительно существует конфликт имен, когда вы регистрируете свое свойство зависимости.

Я не совсем уверен, что это ответ, но я думаю, вам это будет интересно, если вы не знали или не думали об этом раньше.

Я использовал "CheckBox.IsChecked", но, вероятно, будет достаточно любого уникального имени.

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

Это работает без изменения названия вашей собственности.

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

Когда вы создаете имена для своих свойств зависимости, вы должны выбрать уникальные имена, которые не используются для свойств или событий зависимости в каких-либо базовых классах, от которых вы наследуете; в противном случае во время выполнения возникает исключение ArgumentException. Дополнительные сведения о свойствах зависимостей и привязке действий см. В разделах Пример привязки настраиваемого действия и Образец простого действия.

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

Еще одно напоминание, какой я большой новичок :)

person kirotab    schedule 29.10.2015
comment
Это решает мою проблему, хотя я, кажется, не удовлетворяю критерию, согласно которому конфликтующее имя используется для свойств или событий зависимости в любых базовых классах, от которых вы наследуете. Престижность за эту находку. - person Grault; 30.10.2015
comment
Да, он просто не работал со всеми типами привязки, которые я пробовал, не меняя имя или не делая свойство обычным вместо зависимости ... Материал взят из .net 3.5 и не имеет более новой версии (в по крайней мере, я не нашел) так что, может быть, есть изменения ... - person kirotab; 30.10.2015
comment
Нет, чувак, я благодарю вас, потому что у меня были ужасные проблемы с некоторыми свойствами зависимостей, которые я обозначил как Темная Магия в то время (казалось таким нелогичным, как они себя ведут), так что теперь, по крайней мере, у меня есть еще одно оружие, чтобы попытаться сразиться с ними . - person kirotab; 30.10.2015
comment
Странный. Когда я реализовал это в своем реальном проекте, этого не потребовалось. Похоже, мне нужно задать новый вопрос о том, почему это не всегда работает. - person Grault; 30.10.2015
comment
Хм, если вы измените имя класса на что-то 100% уникальное, например asd вместо CheckBox., Если это все еще не работает, просто снимите отметку с ответа, и, возможно, кто-то более умный, чем мы, объяснит. - person kirotab; 30.10.2015