簡體   English   中英

為什么自定義UserControl的依賴項屬性不能與綁定一起使用?

[英]Why does my Custom UserControl's dependency property not work with binding?

如果在調用它的XAML中靜態定義了該值,則我的Custom UserControl的依賴項屬性正確綁定,如下所示:

ItemTypeIdCode="addresses"

但是如果值本身是動態綁定的,則不會:

ItemTypeIdCode="{Binding ItemTypeIdCode}"

我必須對自定義UserControl做些什么,以便其依賴項屬性對另一個控件中綁定的值做出反應?

這是我的代碼:

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>

代碼隱藏:

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


    }
}

我認為您需要將PropertyChangedCallback添加到ItemTypeIdCodeProperty依賴項屬性。 在此回調中,您將調用GetDropDownValues()。

我的猜測是組合框未顯示任何條目。 這確實有些棘手。 控件在2個完全獨立的“地址空間”中工作。 首先是它像所有依賴項屬性一樣是自己的數據。 第二個“地址空間”是它從其父級繼承的數據上下文。 如果沒有特別的事情,所有綁定將在數據上下文上進行。 如果要引用控件的數據,則需要為自己添加一個顯式的“引用”:

<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>

不需要OnPropertyChanged,它已經由依賴項屬性邏輯處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM