لماذا لا تعمل خاصية التبعية الخاصة بـ Custom UserControl مع الربط؟

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

سؤال

خاصية تبعية UserControl المخصصة الخاصة بي سوف ربط بشكل صحيح إذا كانت القيمة بشكل ثابت المعرفة في XAML الذي يطلق عليه، مثل هذا:

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().

نصائح أخرى

تخميني هو أن combobox لا يظهر أي إدخالات. هذا حقا صعب بعض الشيء. يعمل التحكم في 2 "مساحات ADRESS" مستقلة تمامًا. الأول هو أنها بيانات خاصة مثل جميع خصائص التبعية. "مساحة adresse" الثانية هي سياق البيانات الذي يرثه من الوالد. إذا لم يتم القيام بأي شيء خاص ، فكل الروابط تعمل على سياق البيانات. في حال كنت ترغب في الرجوع إلى بيانات عنصر التحكم ، فأنت بحاجة إلى إضافة "مرجع" صريح لنفسك:

<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 مع الإسناد
لا تنتمي إلى StackOverflow
scroll top