Warum funktioniert die Abhängigkeitseigenschaft meines benutzerdefinierten UserControl nicht mit der Bindung?

StackOverflow https://stackoverflow.com/questions/1808204

Frage

Die Abhängigkeitseigenschaft meines benutzerdefinierten UserControl Wille binden Sie korrekt, wenn der Wert ist statisch definiert im XAML, das es aufruft, wie folgt:

ItemTypeIdCode="addresses"

aber nicht, wenn der Wert gebunden ist dynamisch selbst:

ItemTypeIdCode="{Binding ItemTypeIdCode}"

Was muss ich mit meinem benutzerdefinierten UserControl tun, damit seine Abhängigkeitseigenschaft auf den Wert reagiert, der selbst in einem anderen Steuerelement gebunden ist?

Hier ist mein Code:

XAML:

<Window x:Class="TestDepenProp.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:TestDepenProp.Controls"
    Title="Window1" Height="300" Width="300">
    <StackPanel 
        HorizontalAlignment="Left"
        Margin="10">
        <controls:DropDown 
            ItemTypeIdCode="{Binding ItemTypeIdCode}"  
            SelectedValue="672"
            Width="150"
            Margin="0 0 0 5"/>
        <TextBlock Text="{Binding ItemTypeIdCode}"/>
    </StackPanel>
</Window>

Code-Behind:

using System.Windows;
using System.ComponentModel;

namespace TestDepenProp
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {
        #region ViewModelProperty: ItemTypeIdCode
        private string _itemTypeIdCode;
        public string ItemTypeIdCode
        {
            get
            {
                return _itemTypeIdCode;
            }

            set
            {
                _itemTypeIdCode = value;
                OnPropertyChanged("ItemTypeIdCode");
            }
        }
        #endregion

        public Window1()
        {
            InitializeComponent();
            DataContext = this;

            ItemTypeIdCode = "addresses";
        }
        #region INotifiedProperty Block
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }
}

DropDown.xaml:

<UserControl x:Class="TestDepenProp.Controls.DropDown"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <ComboBox SelectedValuePath="Key"
                  DisplayMemberPath="Value"
                  SelectedValue="{Binding SelectedValue}"
                  Margin="0 0 0 10"
                  ItemsSource="{Binding DropDownValues}" />
    </StackPanel>
</UserControl>

DropDown.xaml.cs:

using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Collections.Generic;

namespace TestDepenProp.Controls
{
    public partial class DropDown : UserControl, INotifyPropertyChanged
    {

        public static readonly DependencyProperty ItemTypeIdCodeProperty = DependencyProperty.Register("ItemTypeIdCode", typeof(string), typeof(DropDown));

        public string ItemTypeIdCode
        {
            get { return (string)GetValue(ItemTypeIdCodeProperty); }
            set { SetValue(ItemTypeIdCodeProperty, value); }
        }

        #region ViewModelProperty: DropDownValues
        private ObservableCollection<KeyValuePair<string, string>> _dropDownValues = new ObservableCollection<KeyValuePair<string, string>>();
        public ObservableCollection<KeyValuePair<string, string>> DropDownValues
        {
            get
            {
                return _dropDownValues;
            }

            set
            {
                _dropDownValues = value;
                OnPropertyChanged("DropDownValues");
            }
        }
        #endregion

        #region ViewModelProperty: SelectedValue
        private string _selectedValue;
        public string SelectedValue
        {
            get
            {
                return _selectedValue;
            }

            set
            {
                _selectedValue = value;
                OnPropertyChanged("SelectedValue");
            }
        }
        #endregion

        public DropDown()
        {
            InitializeComponent();
            DataContext = this;

            Loaded += new RoutedEventHandler(DropDown_Loaded);
        }

        void DropDown_Loaded(object sender, RoutedEventArgs e)
        {
            GetDropDownValues();
        }

        void GetDropDownValues()
        {
            switch (ItemTypeIdCode)
            {
                case "addresses":
                    DropDownValues.Add(new KeyValuePair<string, string>("111", "762 Main St."));
                    DropDownValues.Add(new KeyValuePair<string, string>("222", "7384 First Ave."));
                    DropDownValues.Add(new KeyValuePair<string, string>("333", "8728 Second St."));
                    break;
                case "customers":
                    DropDownValues.Add(new KeyValuePair<string, string>("672", "Jim Smith"));
                    DropDownValues.Add(new KeyValuePair<string, string>("281", "James Anders"));
                    DropDownValues.Add(new KeyValuePair<string, string>("321", "Angie Wonderson"));
                    DropDownValues.Add(new KeyValuePair<string, string>("221", "Hal Cloud"));
                    DropDownValues.Add(new KeyValuePair<string, string>("123", "Hugh Brandley"));
                    break;
                default:
                    break;
            }
        }


        #region INotifiedProperty Block
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion


    }
}
War es hilfreich?

Lösung

Ich denke, Sie müssen PropertyChangedCallback zu Ihrer ItemTypeIdCodeProperty-Abhängigkeitseigenschaft hinzufügen.In diesem Rückruf müssen Sie GetDropDownValues() aufrufen.

Andere Tipps

Meine Vermutung ist, dass der Combobox keine Einträge zeigt. Das ist in der Tat ein bisschen schwierig. Eine Kontrolle funktioniert in 2 völlig unabhängigen "Adressräumen". Das erste ist seine eigenen Daten wie alle Abhängigkeitseigenschaften. Der zweite "Adressraum" ist der Datenkontext, den er von seinem Elternteil erbt. Wenn nichts Besonderes getan wird, arbeiten alle Bindungen am Datenkontext. Wenn Sie sich auf die Daten des Steuerelements verweisen möchten, müssen Sie sich selbst eine explizite "Referenz" hinzufügen:

<UserControl x:Class="TestDepenProp.Controls.DropDown"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="self">
<StackPanel>
    <ComboBox SelectedValuePath="Key"
              DisplayMemberPath="Value"
              SelectedValue="{Binding SelectedValue, ElementName=self}"
              Margin="0 0 0 10"
              ItemsSource="{Binding DropDownValues, ElementName=self}" />
</StackPanel>

On -Propertychanged ist nicht benötigt, das wird bereits von der Abhängigkeitseigenschaftslogik behandelt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top