C# 为什么我的自定义用户控件';s的依赖项属性不适用于绑定?
如果值是调用它的XAML中定义的静态值,则自定义UserControl的dependency属性将正确绑定,如下所示:C# 为什么我的自定义用户控件';s的依赖项属性不适用于绑定?,c#,wpf,data-binding,xaml,dependency-properties,C#,Wpf,Data Binding,Xaml,Dependency Properties,如果值是调用它的XAML中定义的静态值,则自定义UserControl的dependency属性将正确绑定,如下所示: ItemTypeIdCode="addresses" 但如果该值是动态绑定的,则不会: ItemTypeIdCode="{Binding ItemTypeIdCode}" 我必须对自定义UserControl做什么才能使它的dependency属性对绑定到另一个控件中的值作出反应? 这是我的密码: XAML: <Window x:Class="TestDepenPro
ItemTypeIdCode="addresses"
但如果该值是动态绑定的,则不会:
ItemTypeIdCode="{Binding ItemTypeIdCode}"
我必须对自定义UserControl做什么才能使它的dependency属性对绑定到另一个控件中的值作出反应?
这是我的密码:
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
}
}
<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>
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
}
}
下拉列表。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
}
}
<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>
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
}
}
下拉列表.xaml.cs:
<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
}
}
<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>
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
}
}
使用System.Windows;
使用System.Windows.Controls;
使用系统组件模型;
使用System.Collections.ObjectModel;
使用System.Collections.Generic;
命名空间TestDepenProp.Controls
{
公共部分类下拉列表:UserControl,INotifyPropertyChanged
{
公共静态只读DependencyProperty ItemTypeIdCodeProperty=DependencyProperty.Register(“ItemTypeIdCode”、typeof(字符串)、typeof(下拉菜单));
公共字符串ItemTypeIdCode
{
获取{return(string)GetValue(ItemTypeIdCodeProperty);}
set{SetValue(ItemTypeIdCodeProperty,value);}
}
#区域ViewModelProperty:DropDownValues
私有ObservableCollection_dropDownValues=新ObservableCollection();
公共可观察收集下拉列表值
{
得到
{
返回_dropdown值;
}
设置
{
_下拉值=值;
OnPropertyChanged(“DropDownValues”);
}
}
#端区
#区域视图模型属性:SelectedValue
私有字符串\u selectedValue;
公共字符串SelectedValue
{
得到
{
返回_selectedValue;
}
设置
{
_selectedValue=值;
OnPropertyChanged(“SelectedValue”);
}
}
#端区
公共下拉列表()
{
初始化组件();
DataContext=this;
已加载+=新路由EventHandler(下拉菜单\u已加载);
}
已加载无效下拉列表(对象发送器、路由目标)
{
GetDropDownValues();
}
void GetDropDownValues()
{
开关(ItemTypeIdCode)
{
案例“地址”:
添加(新的键值对(“111”,“762大街”);
添加(新的KeyValuePair(“222”、“7384第一大道”);
添加(新的键值对(“333”,“8728秒圣”);
打破
案例“客户”:
添加(新的键值对(“672”,“Jim Smith”);
添加(新的KeyValuePair(“281”,“James Anders”);
添加(新的KeyValuePair(“321”,“Angie Wonderson”);
添加(新的KeyValuePair(“221”,“Hal云”);
添加(新的KeyValuePair(“123”,“Hugh Brandley”);
打破
违约:
打破
}
}
#区域INotifiedProperty块
公共事件属性更改事件处理程序属性更改;
受保护的无效OnPropertyChanged(字符串propertyName)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
{
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
}
#端区
}
}
我认为您需要将PropertyChangedCallback添加到ItemTypeIdCodeProperty依赖属性中。在此回调中,您将调用GetDropDownValues()。我认为您需要将PropertyChangedCallback添加到ItemTypeIdCodeProperty依赖属性中。在此回调中,您将调用GetDropDownValues()。我猜组合框不会显示任何条目。这确实有点棘手。控件在两个完全独立的“地址空间”中工作。第一个是它自己的数据,就像所有依赖属性一样。第二个“ADRESE空间”是它从其父级继承的数据上下文。如果没有执行任何特殊操作,则所有绑定都会在数据上下文上工作。如果要引用控件的数据,则需要为自己添加一个明确的“引用”:
<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,这已经由依赖属性逻辑处理。我猜组合框不显示任何条目。这确实有点棘手。控件在两个完全独立的“地址空间”中工作。第一个是它自己的数据,就像所有依赖属性一样。第二个“ADRESE空间”是它从其父级继承的数据上下文。如果没有执行任何特殊操作,则所有绑定都会在数据上下文上工作。如果要引用控件的数据,则需要为自己添加一个明确的“引用”:
<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,这已经由依赖属性逻辑处理