【发布时间】:2014-04-13 13:30:41
【问题描述】:
我有一个自定义控件:
我不想详细说明,所以为了简单起见,我有 3 个依赖属性:
MyCustomControl (CS):
public class MyCustomControl : Control
{
DP Value1
DP InternalValue
DP SelectedValue
OnValue1Changed()
{
InternalValue = CalculateBasedOn1();
}
static bool _isSetInternally;
OnInternalValueChanged()
{
if(Condition())
{
_isSetInternally = true;
SelectedValue = e.NewValue;
}
else
{
Value1 = FixValue1();
}
}
OnSelectedValueChanged()
{
if(_isSetInternally)
{
_isSetInternally = false;
return;
}
Value1 = ExtractValue1FromInput(e.NewValue);
}
public List<string> Values
{
get{ return new List<string>() { "1","2",......,"200"};}
}
}
我的 ControlTemplate(再次简化):
<ControlTemplate>
<ComboBox x:Name="cb"
ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay, Path=Values}"
SelectedItem={Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
</ControlTemplate>
问题: cb 显示的是最后选择的值,即使它已按如下所述进行修复。
流程:
1) 输入:
1.1) SelectedValue 绑定到我的 DataContext 中的一个属性,它接收一个值。
1.2) OnSelectedValueChanged() 设置 Value1。
1.3) Value1 通过绑定设置“cb”SelectedItem。
1.4) OnValue1Changed 设置 InternalValue。
1.5) OnInternalValueChanged() 标志 _isSetInternally = true 并更新 SelectedValue。
1.6) OnSelectedValueChanged() 将 _isSetInternally = false 归零并停止流动(返回)。
2) 输出:
2.1) cb 的 SelectedItem 发生了变化。
2.2) Value1 通过 Binding 设置。
2.3) OnValue1Changed() 设置 InternalValue。
2.4) 如果满足条件,则传播输出。
2.4.1) 转到 (1.4)
2.4.2) 问题,不满足条件,重新设置 Value1 为有效值。
2.5) 转到 (1.4)
2.4.2中的问题是ComboBox仍然显示在(2.1)中选择的无效值
用 snoop 观察我可以看到 SelectedItem 是正确的并且已更改,但 SelectedValue 和 SelectedIndex 仍然是在修复之前选择的。
*进一步尝试在强制回调上强制 Value1 ,它具有相同的效果。
知道为什么 ComboBox 在这种情况下不通过绑定更新它的值吗?
【问题讨论】:
-
仅供参考,我还尝试了绑定到 SelectedValue 而不是 SelectedItem 并使用 OneWay 绑定使用 SelectedValue 绑定到它们。
标签: wpf custom-controls dependency-properties