2015-10-29 10 views
6

Usando:XAML: Come posso associare una proprietà di dipendenza ad una proprietà C# con lo stesso nome su un oggetto diverso?

  • Visual Studio Community Edition 2015
  • Net 4,0

Ho implementato this answer, producendo il mio CheckBox classe completo di una IsCheckedDependencyProperty. Quella proprietà è supportata dalla proprietà IsChecked sul WPF CheckBox o sarebbe se funzionasse. Lavorare significherebbe che il mio getter e setter vengono chiamati quando la casella di controllo è attivata.

Se rinominare la proprietà su IsChecked_temp e modificare XAML in modo che corrisponda, funziona correttamente. Penso che questo sia un conflitto di denominazione, ma perché non lo risolve ElementName? Segue il mio caso di test minimale.

MODIFICA 0: ho dimenticato di menzionare, non ricevo errori o avvisi.

EDIT 1: This answer è stato inizialmente accettato perché funziona per il caso di test, ma apparentemente non è l'intera risposta. Applicandola al mio progetto (e rinominare la classe CheckBox a ToggleBox) produce un XamlParseException ad ogni utilizzo della proprietà:

A 'vincolante' non può essere impostato sulla proprietà 'IsChecked' di tipo 'ToggleBox'. Un 'Binding' può essere impostato solo su una DependencyProperty di DependencyObject.

Cercherò di ottenere un test case minimale che mostri questo.

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 (per completezza)

using System.Windows; 

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

Proprio per la prova, cerco di scrivere IsChecked = "{Binding Path = IsChecked, ElementName = self}" – Spawn

+1

@Spawn L'ho provato con e senza '_temp' e ho ottenuto gli stessi risultati. Vale la pena provare, quindi grazie. – Grault

+0

Ok, ci proverò domani ... Self non è un nome così raro per UserControl, quindi deve funzionare. Puoi dire quale versione di Visual Studio e .NET usi? – Spawn

risposta

1

domanda molto interessante (almeno per me) Così si scopre che c'è davvero un conflitto di nomi quando si registra la proprietà di dipendenza.

Non sono proprio sicuro se questa è una risposta, ma penso che la troverai interessante se non lo avessi saputo o pensato prima.

Ho usato "CheckBox.IsChecked", ma probabilmente un nome univoco sarebbe sufficiente.

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

Questo funziona senza modifiche in nome della vostra proprietà

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

Quando si creano nomi per le proprietà di dipendenza, è necessario scegliere nomi unici che non vengono utilizzati per le proprietà di dipendenza o eventi in qualsiasi classe base da cui si eredita; in caso contrario, viene generata una ArgumentException durante il runtime. Per ulteriori informazioni sulle proprietà di dipendenza e il binding di attività , vedere Attività personalizzata Campione di associazione e Esempio di attività semplice.

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

Ancora un altro ricordo come grande di un noob Sono :)

+0

Huh. Non sto ottenendo un ArgumentException, ma lemme scappare e provare questo ... – Grault

+0

Questo risolve il mio problema, anche se non sembro soddisfare i criteri che il nome in conflitto è "utilizzato per proprietà di dipendenza o eventi in qualsiasi base classi da cui si eredita. " Complimenti per questa scoperta. – Grault

+0

Sì, semplicemente non funzionava con tutti i tipi di binding che ho provato senza modificare il nome o rendere normale la proprietà anziché la dipendenza ... Il materiale proviene da .net 3.5 e non ha una versione più recente (almeno non ne ho trovato uno) quindi forse ci sono cambiamenti ... – kirotab

Problemi correlati