为什么我的用户控件与组合框绑定不正确?
Why isn't my user control with a combobox binding correctly?
我尝试创建一个非常简单的 UserControl,其中包含美国各州的列表。我正在尝试通过 "SelectedState" 属性 公开所选状态。但是,一旦它连接到另一个 UserControl / 表单,我就无法尝试触发此绑定。
用户控件的 XAML 如下所示:
<UserControl x:Class="Sample.Desktop.UserControls.StateDropdown"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Sample.Desktop.UserControls"
mc:Ignorable="d"
Width="170" Height="28"
d:DesignHeight="28" d:DesignWidth="170">
<ComboBox x:Name="cboState"
ItemsSource="{Binding StateList, RelativeSource={RelativeSource AncestorType=UserControl}}"
SelectedValue="{Binding SelectedState, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Abbreviation}"></Label>
<Label> - </Label>
<Label Content="{Binding Name}"></Label>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
在代码隐藏中,我有这段代码:
public static readonly DependencyProperty SelectedStateProperty = DependencyProperty.Register("SelectedState",
typeof(USState),
typeof(StateDropdown),
new UIPropertyMetadata(null,
new PropertyChangedCallback(OnSelectedStateChanged),
new CoerceValueCallback(OnCoerceSelectedState)));
private static object OnCoerceSelectedState(DependencyObject o, object value)
{
StateDropdown stateDropdown = o as StateDropdown;
if (stateDropdown != null)
return stateDropdown.OnCoerceSelectedState((USState)value);
else
return value;
}
private static void OnSelectedStateChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
StateDropdown stateDropdown = o as StateDropdown;
if (stateDropdown != null)
stateDropdown.OnSelectedStateChanged((USState)e.OldValue, (USState)e.NewValue);
}
protected virtual USState OnCoerceSelectedState(USState value)
{
// TODO: Keep the proposed value within the desired range.
return value;
}
protected virtual void OnSelectedStateChanged(USState oldValue, USState newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
public USState SelectedState
{
// IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!
get
{
return (USState)GetValue(SelectedStateProperty);
}
set
{
SetValue(SelectedStateProperty, value);
}
}
我无法触发 SelectedState 的 SelectedValue 绑定 属性,所以我最终连接了 SelectionChanged 事件。
private void cboState_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems?.Count > 0)
{
SelectedState = (USState)e.AddedItems[0];
}
}
在我的其他用户控件中,XAML:
<uc:StateDropdown Margin="10,0,0,0" SelectedState="{Binding SelectedState}" ></uc:StateDropdown>
还有 ViewModel(我使用的是 Caliburn Micro),我有这个 属性:
protected USState _selectedState;
public USState SelectedState
{
get { return _selectedState; }
set
{
_selectedState = value;
NotifyOfPropertyChange(() => SelectedState);
}
}
组合已按预期填充。但是,当我更改选择时,SelectedState 永远不会 fired/updated 。
我之前也尝试过使用 SelectedItem 而不是 SelectedValue,结果相同。
我确定我遗漏了一些明显的东西,但我很难看出哪里出错了。
编辑:这是修复绑定的内容。
我删除了 SelectionChanged 事件。然后我修改了 "hosting page" 用户控件以设置双向绑定:
<uc:StateDropdown Margin="10,0,0,0" SelectedState="{Binding SelectedState, Mode=TwoWay}" ></uc:StateDropdown>
我一添加,SelectedState 就在我更改 ComboBox 值时开始更新。
我唯一看到的是这一行:
SelectedValue="{Binding SelectedState, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}"
您不需要它,因为发生了 SelectionChanged 事件。它可能会导致问题。
另外,我会使用 TwoWay 绑定来绑定 UserControl 的 SelectedState。
希望对你有所帮助。
我尝试创建一个非常简单的 UserControl,其中包含美国各州的列表。我正在尝试通过 "SelectedState" 属性 公开所选状态。但是,一旦它连接到另一个 UserControl / 表单,我就无法尝试触发此绑定。
用户控件的 XAML 如下所示:
<UserControl x:Class="Sample.Desktop.UserControls.StateDropdown"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Sample.Desktop.UserControls"
mc:Ignorable="d"
Width="170" Height="28"
d:DesignHeight="28" d:DesignWidth="170">
<ComboBox x:Name="cboState"
ItemsSource="{Binding StateList, RelativeSource={RelativeSource AncestorType=UserControl}}"
SelectedValue="{Binding SelectedState, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Abbreviation}"></Label>
<Label> - </Label>
<Label Content="{Binding Name}"></Label>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
在代码隐藏中,我有这段代码:
public static readonly DependencyProperty SelectedStateProperty = DependencyProperty.Register("SelectedState",
typeof(USState),
typeof(StateDropdown),
new UIPropertyMetadata(null,
new PropertyChangedCallback(OnSelectedStateChanged),
new CoerceValueCallback(OnCoerceSelectedState)));
private static object OnCoerceSelectedState(DependencyObject o, object value)
{
StateDropdown stateDropdown = o as StateDropdown;
if (stateDropdown != null)
return stateDropdown.OnCoerceSelectedState((USState)value);
else
return value;
}
private static void OnSelectedStateChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
StateDropdown stateDropdown = o as StateDropdown;
if (stateDropdown != null)
stateDropdown.OnSelectedStateChanged((USState)e.OldValue, (USState)e.NewValue);
}
protected virtual USState OnCoerceSelectedState(USState value)
{
// TODO: Keep the proposed value within the desired range.
return value;
}
protected virtual void OnSelectedStateChanged(USState oldValue, USState newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
public USState SelectedState
{
// IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!
get
{
return (USState)GetValue(SelectedStateProperty);
}
set
{
SetValue(SelectedStateProperty, value);
}
}
我无法触发 SelectedState 的 SelectedValue 绑定 属性,所以我最终连接了 SelectionChanged 事件。
private void cboState_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems?.Count > 0)
{
SelectedState = (USState)e.AddedItems[0];
}
}
在我的其他用户控件中,XAML:
<uc:StateDropdown Margin="10,0,0,0" SelectedState="{Binding SelectedState}" ></uc:StateDropdown>
还有 ViewModel(我使用的是 Caliburn Micro),我有这个 属性:
protected USState _selectedState;
public USState SelectedState
{
get { return _selectedState; }
set
{
_selectedState = value;
NotifyOfPropertyChange(() => SelectedState);
}
}
组合已按预期填充。但是,当我更改选择时,SelectedState 永远不会 fired/updated 。
我之前也尝试过使用 SelectedItem 而不是 SelectedValue,结果相同。
我确定我遗漏了一些明显的东西,但我很难看出哪里出错了。
编辑:这是修复绑定的内容。
我删除了 SelectionChanged 事件。然后我修改了 "hosting page" 用户控件以设置双向绑定:
<uc:StateDropdown Margin="10,0,0,0" SelectedState="{Binding SelectedState, Mode=TwoWay}" ></uc:StateDropdown>
我一添加,SelectedState 就在我更改 ComboBox 值时开始更新。
我唯一看到的是这一行:
SelectedValue="{Binding SelectedState, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}"
您不需要它,因为发生了 SelectionChanged 事件。它可能会导致问题。
另外,我会使用 TwoWay 绑定来绑定 UserControl 的 SelectedState。
希望对你有所帮助。