【问题标题】:Is there a way to bind 2 (or more) WPF items to a single property in C#?有没有办法将 2 个(或更多)WPF 项绑定到 C# 中的单个属性?
【发布时间】:2016-01-16 22:54:04
【问题描述】:

我的班级包含一个address 属性(字符串类型),但我的 WPF 窗口包含一些地址文本框(门牌号、街道名称和可选的第二行地址 - 城镇和邮政编码在班上)。 我想将它们全部放入班级中的单个address 字符串中,用逗号分隔(例如“43, Whitefield Road, Princesshire”)。有没有办法通过绑定来实现,还是只能在代码中手动实现?

【问题讨论】:

  • 你最好让你的模型反映你如何需要这些绑定。您可以使用一个单独的类将这些中的每一个都公开为属性,然后它可以将这些属性组合成一个字符串。
  • 我同意。您可以使用如下所示的转换器,但这确实是您应该能够在没有视图妨碍的情况下进行单元测试的东西。如果您发现自己必须使用转换器来实现除最基本逻辑之外的任何东西,那么这通常是一个好兆头,表明您要绑定的模型(例如 mvvm 的视图模型)没有正常工作。

标签: c# wpf data-binding


【解决方案1】:

将所有字段绑定到类的 Address 属性,然后使用值转换器确定地址的哪些组件适用。在转换器中有一个属性允许您确定要操作的子字符串:

public class AddressSeparatorConverter : IValueConverter
{
    ///<summary>
    /// Index of the substring element of the address to be manipulated (read/edited).
    ///</summary>
    public int SubStringIdx { get; set; }

    ...
}

然后在执行转换时,只需使用 , 分隔符拆分字符串并返回 SubStringIdx 指定的子字符串:

address.Split(',')[SubStringIdx]

当您绑定到可编辑控件时,您需要确保为 IValueConverter.ConvertIValueConverter.ConvertBack 方法提供实现。

为了更进一步,您可以在 Converters.xaml 文件中提供不同的转换器定义来处理地址的各种子组件:

<converters:AddressSeparatorConverter x:Key="AddressToHouseNumberConverter" SubStringIdx="0"/>
<converters:AddressSeparatorConverter x:Key="AddressToStreetNameConverter" SubStringIdx="1"/>
...

然后,当绑定到您的控件时,您将通过其键调用适当的转换器:

<TextBox Text="{Binding Address, Converter={StaticResource AddressToStreetNameConverter}}"/>

我现在无法访问 IDE,因此请接受代码 sn-ps 可能不是 100% 正确,但您应该了解它的要点。

【讨论】:

  • 老实说,虽然我已经提出了将地址作为单个字段的解决方案,因为它实际上是一个复合字段,将其拆分为单独的属性会更清晰。
【解决方案2】:

使用多重绑定:

地址文本框文本绑定的语法是:

<TextBox Width="100" >
        <TextBox.Text>
            <MultiBinding Converter="{StaticResource YourAddressConverter}">
                //order below bindings as you want them in the array passed to converter
                <Binding ElementName="Houseblock" Path="Text"/>
                <Binding ElementName="streetblock" Path="Text"/>
                 .......................
                <Binding ElementName="townblock" Path="Text"/>
            </MultiBinding>
        </TextBox.Text>
    </TextBox>

使用 elementbinding 将其他文本框的文本绑定到 finaltextbox(address) 并且 YourAddressConverter 是一个转换器,它将包含地址组件连接的登录,如下所示这是转换方法。

public class YourAddressConverter : IMultiValueConverter
{

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return values[0].ToString() + " " + values[1].ToString();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

这是最简单和最好的解决方案。

【讨论】:

    【解决方案3】:

    如果您创建一个 Address 对象,其中包含门牌号、街道名称、邮政编码等单独的字段,您可以单独绑定到每个字段。

    如果你想打印出整个地址,你可以创建一个只读属性,它将地址的各个部分组合成一个字符串:

    public string SingleLineFormat
    {
        get
        {
            return string.Format("{0} {1}, {2}, {3}", this.Number, this.Street, this.Town, this.PostCode);
        }
    }
    

    您甚至可以有不同的版本,返回多行格式的字符串,或者根据需要使用不同的地址组合。

    public string MultiLineFormat
    {
        get
        {
            return string.Format("{0} {1}{4} {2}{4} {3}", this.Number, this.Street, this.Town, this.PostCode, Environment.NewLine);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多