2015-10-29 4 views
6

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

  • Visual Studio Community Edition 2015
  • .Net 4,0

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

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

EDIT 0: Я забыл упомянуть, у меня нет никаких ошибок или предупреждений.

EDIT 1: This answer был первоначально принят, потому что он работает для тестового примера, но, по-видимому, это не весь ответ. Применяя его к моему проекту (и переименование CheckBox класса ToggleBox) дает XamlParseException при каждом использовании объекта:

А «Binding» не может быть установлено на свойстве «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(); 
     } 
    } 
} 
+1

Просто для теста, попробуйте написать IsChecked = "{Binding Path = IsChecked, ElementName = Само}" – Spawn

+1

@Spawn Я пробовал это с помощью и без '_temp' и получил те же соответствующие результаты. Стоит попробовать, хотя, спасибо. – Grault

+0

Хорошо, я постараюсь завтра ... Я не очень редкое имя для UserControl, поэтому он должен работать. Можете ли вы сказать, какую версию Visual Studio и .NET вы используете? – Spawn

ответ

1

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

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

Я использовал «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

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

+0

Huh. Я не получаю ArgumentException, но lemme убежал и попробовал это ... – Grault

+0

Это решает мою проблему, хотя я, похоже, не удовлетворяю критериям, которые конфликтующее имя «используется для свойств зависимостей или событий в любой базе классы, которые вы наследуете ». Престижность этой находки. – Grault

+0

Да, это просто не работало со всеми типами привязки, которые я пробовал, не меняя имени, или делаю свойство нормальным, а не зависимым ... Материал от .net 3.5 и не имеет более новой версии (по крайней мере, я его не нашел), поэтому, возможно, есть изменения ... – kirotab

Смежные вопросы