2015-10-29 26 views
6

Zastosowanie:XAML: Jak powiązać właściwość DependencyProperty z właściwością C# o tej samej nazwie na innym obiekcie?

  • Visual Studio Community Edition 2015
  • Net 4,0

I zostały wdrożone this answer, produkując własne CheckBox klasę komplecie z IsCheckedDependencyProperty. Ta właściwość jest wspierana przez właściwość IsChecked na WPF CheckBox lub byłaby, gdyby działała. Praca oznaczałaby, że mój odbiorca i seter są wywoływani, gdy pole wyboru jest przełączane.

Jeśli zmienię nazwę mojej nieruchomości na IsChecked_temp i zmodyfikuję XAML tak, aby pasowała, działa dobrze. Myślę, że to konflikt nazw, ale dlaczego go nie rozwiąże? Mój minimalny przypadek testowy następuje.

EDYCJA 0: Zapomniałem wspomnieć, nie otrzymuję żadnych błędów ani ostrzeżeń.

EDIT 1: This answer został początkowo zaakceptowany, ponieważ działa w przypadku testowym, ale najwyraźniej nie jest to cała odpowiedź. Stosując ją do mojego projektu (i zmiana nazwy klasy CheckBox do ToggleBox) daje XamlParseException przy każdym użyciu nieruchomości:

A „wiążące” nie można ustawić na własność „IsChecked” typu „ToggleBox”. "Powiązanie" można ustawić tylko na DependencyProperty obiektu DependencyObject.

Postaram się uzyskać minimalny przykład testowy, aby to pokazać.

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 (dla kompletności)

using System.Windows; 

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

Tylko dla testu, spróbuj napisać IsChecked = "{Binding Path = IsChecked, ElementName = self}" – Spawn

+1

@Spawn Próbowałem tego zi bez '_temp' i otrzymałem takie same wyniki. Warto spróbować, więc dzięki. – Grault

+0

OK, spróbuję jutro ... Self nie jest tak rzadką nazwą UserControl, więc musi działać. Czy możesz powiedzieć, jakich wersji Visual Studio i .NET używasz? – Spawn

Odpowiedz

1

Bardzo interesujące pytanie (przynajmniej dla mnie), więc okazuje się, że jest naprawdę konflikt z nazwami po zarejestrowaniu Dependency nieruchomości.

Nie jestem do końca pewien, czy to jest odpowiedź, ale myślę, że uznasz to za interesujące, jeśli wcześniej o tym nie wiedziałeś lub nie myślałeś.

Użyłem "CheckBox.IsChecked", ale każda unikalna nazwa będzie prawdopodobnie wystarczająca.

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

Działa to bez zmian w imię swojej własności

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

Podczas tworzenia nazwy dla swoich właściwości zależności, należy wybrać unikatowych nazw, które nie są wykorzystywane do właściwości zależność lub zdarzeń w dowolnych klasach bazowych, z których dziedziczysz; w przeciwnym razie podczas środowiska wykonawczego zostanie zgłoszony wyjątek ArgumentExule . Aby uzyskać więcej informacji na temat właściwości zależności i powiązania aktywności , zobacz Niestandardowa aktywność Próbka wiązania i próbka prostej aktywności.

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

kolejne przypomnienie jak duży noob jestem :)

+0

Huh. Nie dostaję ArgumentException, ale lemme uciekł i spróbuj tego ... – Grault

+0

Rozwiązuje to mój problem, mimo że nie spełnia kryteriów, że nazwa konfliktu jest "używana dla właściwości zależności lub zdarzeń w dowolnej bazie klasy, z których dziedziczysz. " Kudos za to odkrycie. – Grault

+0

Tak, po prostu nie działał ze wszystkimi typami powiązań, które próbowałem bez zmiany nazwy lub uczynienia właściwości normalną zamiast zależności ... Materiał pochodzi z .net 3.5 i nie ma nowszej wersji (przynajmniej go nie znalazłem), więc może są zmiany ... – kirotab