c# - 在显示该项目上也定义的预设列表中的友好名称时绑定(bind)到值的正确方法是什么?

标签 c# wpf binding ivalueconverter imultivalueconverter

有一个艰难的。考虑一个由对象列表组成的 ViewModel,其中每个对象都定义一个 int 值,并且其中一些对象还定义了一个 Presets 字典,该字典以表示 UI 中该值的“友好”字符串为键。

这是一个例子...

List<SomeItem> AllItems;

public class SomeItem : INotifyPropertyChanged
{
    public SomeItem(int initialValue, Dictionary<int,string> presets)
    {
        this.CurrentValue = initialValue;
        this.Presets = presets;
    }
    public int CurrentValue{ get; set; } // Shortened for readability. Assume this property supports INPC
    public Dictionary<int,string> Presets{ get; private set; }
}

UI 的目标是如果项目没有预设,用户可以输入他们想要的任何 int 值。但是,如果有 预设,我们希望将它们限制为这些值,并将它们作为字典中的友好名称显示在 UI 中。

我们的第一个尝试是使用一个 TextBox 和一个 ComboBox,根据是否有预设来修改它们的可见性,就像这样......

<ComboBox ItemsSource="{Binding Presets}"
    DisplayMemberPath="Key"
    SelectedValuePath="Value"
    SelectedValue="{Binding CurrentValue, Mode=TwoWay}"
    Visibility={Binding HasPresets, Converter=...}">

<TextBox Text="{Binding CurrentValue}"
    Visibility={Binding HasPresets, Converter...}" /> // Assume the inverse of the combo

...但是当我们在支持虚拟化的列表的 DataTemplate 中使用它时,组合偶尔会显示空白。我相信是因为当项目被重复使用并且 DataContext 发生变化时,SelectedValue 在 ItemsSource 之前更新意味着可能没有预设值可以匹配,因此建议的 SelectedValue 值被控件抛出,然后 ItemsSource 更新,但没有选定的值,因此它显示为空白。

我的下一个想法(无论如何我们更喜欢)是只使用一个显示预设名称但实际上绑定(bind)到值的文本框,然后使用一个转换器来发挥它的魔力,让用户输入友好的名称或实际值。如果用户键入的内容不是有效值或预设值,我们只会抛出一个错误。如果没有预设,它只会充当值的传递。

但是,我不确定如何将预设传递给转换器。您不能在 ConverterParameter 上设置绑定(bind)以这种方式传递它们,如果您使用多重绑定(bind),那么我不确定如何构造“ConvertBack”调用,因为我也需要它们传入,而不是送回。

我认为正确的方法是在 ViewModel 中实现 UiValue,我们只需像这样绑定(bind)它...

<TextBox Text="{Binding UiValue}" />

...然后将本应在转换器中的代码移动到该属性的 getter/setter 实现,或者如果没有预设,则只是传递给 Value。然而,这似乎在 ViewModel 中发生了太多逻辑,而它应该在 View 中(ala 转换器或类似的)。然后,也许这正是 ViewModel 的重点。我不知道。欢迎提出想法。

最佳答案

就个人而言,我会按照您的建议将“转换器代码”放入属性中……我认为将代码放在那里没有任何问题。事实上,它可能比将它放在 Converter 中更好,因为那样您也可以轻松地测试它。

抱歉,这不是一个很好的答案,但我觉得你的问题至少值得一个。

关于c# - 在显示该项目上也定义的预设列表中的友好名称时绑定(bind)到值的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18736899/

相关文章:

c# - 用于显示程序集名称的数据绑定(bind)

c# - 单个 TextBlock 中的替代文本

c# - 如何在 WPF 窗口中 move 网格面板

c# - 如何在代码中绑定(bind)嵌套对象或主从绑定(bind)?

c# - 我们如何递归地组装准备好的语句

c# - .NET 的免费 UML 绘图库

WPF:将标志与复选框绑定(bind)

c# - 如何从特定绑定(bind) C# 获取证书

c# - 在 C# 中找不到 ExtractToDirectory

c# - RowDefinition 上的 MouseEnter/MouseLeave