Problem mit DependencyProperty im Control

dredav
Hallo,

ich erstelle ein Control welches ein ComboBoxItem beinhaltet. Das Control selber beinhaltet hier im Beispiel jetzt nur eine CheckBox, welche via Binding checked und enabled ist. Der Sinn dahinter ist es, ein Complexes ComboBoxItem, welches öfters verwendet wird, so einfach wie möglich zu erstellen.

Control.xaml

XML-Code:
<ComboBoxItem x:Class="WpfApplication1.MyCombobox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Height="50"
             Width="200"
>
    <!-- ... -->
    <StackPanel>
        <CheckBox IsChecked="{Binding Path=IsCheckboxChecked}" IsEnabled="{Binding Path=IsCheckboxEnabled}">
            <CheckBox.LayoutTransform>
                <ScaleTransform ScaleX="1" ScaleY="1" />
            </CheckBox.LayoutTransform>
        </CheckBox>
        <!-- ... -->
    </StackPanel>
</ComboBoxItem>

Control.xaml.cs

C#-Code:
public partial class MyCombobox
{
    public MyCombobox()
    {
        InitializeComponent();
        DataContext = this;

        //Defaults
        IsCheckboxChecked = false;
        IsCheckboxEnabled = true;

        //...
    }

    //...

    public string Text { get; set; }

    public bool IsCheckboxChecked { get; set; }

    public bool IsCheckboxEnabled { get; set; }

    //...
}

Aufruf des Controls

XML-Code:
<WpfApplication1:MyCombobox IsCheckboxChecked="{Binding Path=IsMyCheckBoxChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsCheckboxEnabled="{Binding Path=IsMyCheckBoxEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Text="Write your Text here" />

Nur leider geht das nicht, da in der CodeBehind Datei die Eigenschaften Text, IsCheckboxChecked, IsCheckboxEnabled ja DependencyPropertys sein müssen, das würde dann so aussehen:

C#-Code:
        public static readonly DependencyProperty IsCheckboxCheckedProperty = DependencyProperty.Register("IsCheckboxChecked", typeof(bool), typeof(ComboBoxCheckboxItem));
        public bool IsCheckboxChecked
        {
            get { return (bool)GetValue(IsCheckboxCheckedProperty); }
            set { SetValue(IsCheckboxCheckedProperty, value); }
        }

        public static readonly DependencyProperty IsCheckboxEnabledProperty = DependencyProperty.Register("IsCheckboxEnabledProperty", typeof(bool), typeof(ComboBoxCheckboxItem));
        public bool IsCheckboxEnabled
        {
            get { return (bool)GetValue(IsCheckboxEnabledProperty); }
            set { SetValue(IsCheckboxEnabledProperty, value); }
        }

dazu müsste die Klasse MyCombobox von DependencyObject erben. Was aber nicht geht da sie ja schon (über den xaml code) von ComboBoxItem erbt.

Wie kann ich das ganze anders lösen? Wie würdet ihr das machen?

Danke und Grüße
David
redMars
Hi dredav,

ich versteh das Problem nicht so ganz. Wenn du eine Ableitung von ComboBoxItem machst, dann ist das automatisch auch eine Ableitung von DependencyObject, da ComboBoxItem wie folgt abgeleitet ist:
DependencyObject --> Visual --> UIElement --> FrameworkElement --> Control --> ContentControl --> ListBoxItem --> ComboBoxItem

Demzufolge kannst du ganz normal DependencyProperties deklarieren...

Viele Grüße
redMars
dredav
Das ist die aktuelle CodeBehind Datei:

C#-Code:
public partial class MyCombobox
{
    public MyCombobox()
    {
        InitializeComponent();
        DataContext = this;

        //Defaults
        IsCheckboxChecked = false;
        IsCheckboxEnabled = true;

        //...
    }

    //...

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(ComboBoxCheckboxItem));
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public static readonly DependencyProperty IsCheckboxCheckedProperty = DependencyProperty.Register("IsCheckboxChecked", typeof(bool), typeof(ComboBoxCheckboxItem));
        public bool IsCheckboxChecked
        {
            get { return (bool)GetValue(IsCheckboxCheckedProperty); }
            set { SetValue(IsCheckboxCheckedProperty, value); }
        }

        public static readonly DependencyProperty IsCheckboxEnabledProperty = DependencyProperty.Register("IsCheckboxEnabledProperty", typeof(bool), typeof(ComboBoxCheckboxItem));
        public bool IsCheckboxEnabled
        {
            get { return (bool)GetValue(IsCheckboxEnabledProperty); }
            set { SetValue(IsCheckboxEnabledProperty, value); }
        }

    //...
}

Wenn ich nun den Aufruf wie oben (erste Beitrag) machen, bekomme ich trotz meiner DependencyPropertys folgenden Fehler:

Zitat:
A fatal error occurred: a 'Binding' cannot be set on the 'IsCheckboxEnabled' property of type 'MyCombobox'. A 'Binding' can only be set on a Dependency Property of a DependencyObject
winSharp93
Naja - von ComboBoxItem solltest du natürlich schon ableiten Augenzwinkern
dredav
Zitat von winSharp93:
Naja - von ComboBoxItem solltest du natürlich schon ableiten ;)

tue ich ja =) (in der xaml file)

Aber ich habe den Fehler gefunden, ich kann das Programm wieder starten

C#-Code:
public static readonly DependencyProperty IsCheckboxEnabledProperty = DependencyProperty.Register("IsCheckboxEnabledProperty", typeof(bool), typeof(ComboBoxCheckboxItem));

Es muss im Register IsCheckboxEnabled heißen und nicht IsCheckboxEnabledProperty -.-

Grüße
David
dredav
Gute Morgen,

also ich bin jetzt einen Schritt weiter gekommen:

Wenn ich mein Control aufrufe mit dem folgendem xaml code erhate ich BindingExpressions, das IsMyCheckBoxChecked, IsMyCheckBoxEnabled nicht gefunden werden können:

XML-Code:
<WpfApplication1:MyCombobox IsCheckboxChecked="{Binding Path=IsMyCheckBoxChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsCheckboxEnabled="{Binding Path=IsMyCheckBoxEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Text="Write your Text here" />

Wie ich fest gestellt habe liegt es an dem DataContext im Konstruktor von MyCombobox. Wenn ich den call auskommentiere geht aber das Binding in meinem Control (Das Control.xaml Control) nicht mehr.

C#-Code:
    public MyCombobox()
    {
        InitializeComponent();
        DataContext = this;

        //Defaults
        IsCheckboxChecked = false;
        IsCheckboxEnabled = true;

        //...
    }

Wie kann ich das lösen?
c#arp
Der DataContext hat offensichtlich keine Property namens "IsMyCheckBoxChecked"
Und zwar der DataContext der UI-Elements, das MyCombox verwendet.

Du solltest übrigens - für meinen Geschmack - Dein MyCombobox als Custom Control implementieren, und das XAML als ControlTemplate "anbinden"
Die DPs kannst Du dann über TemplateBinding statt FindAncestor anbinden.
Das ist sozusagen "sauberer".

Gruß,
Christoph