WPF MVVM 与特定类型的绑定

WPF MVVM binding with specific types

我试图在我的 WPF 应用程序中实现 MVVM 设计模式,但我在将视图与视图模型绑定时遇到了一些问题。

在我的一个 ViewModel 中,我有以下 属性:

public IPEndPoint EndPoint
{
    get { return _serverInfos.EndPoint; }
    private set
    {
        _serverInfos.EndPoint = value;
        RaisePropertyChanged("EndPoint");
    }
}

我想像这样在相关视图中绑定此 属性:

<TextBox Text="{Binding EndPoint.Address}" />
<TextBox Text="{Binding EndPoint.Port}" />

EndPoint.Port 绑定按预期工作,但另一个绑定不起作用,因为 EndPoint.Address 不是字符串(它是 IP 地址)。当然,我可以定义两个字符串属性而不是一个 IPEndPoint,但我认为这不是一个好的解决方案。

当我想将枚举转换为 int 时,我在使用枚举时也遇到了同样的问题:

<ComboBox SelectedIndex="{Binding MyEnumProperty}" />

我该如何解决这些问题?

感谢您的帮助。

通常您希望视图模型从模型中获取内容并以视图可以使用的方式公开它们。因此

  1. MyEnumProperty 应该是 System.Int32 (int) 对于 ComboBox.SelectedIndex 到消费者
  2. 您可能应该为 EndPointPortEndPointAddress 实现两个单独的属性,并且 EndPointAddress 应该是一个 string,在工作时转换为 IPAddress与模特

你可以对这两个都使用 IValueConverters,但是如果它所做的只是像模型一样,那么你首先会减少单独视图模型的一些效用。

就 IPEndPoint 类型而言,这是类型转换器 (IValueConverter) 的完美案例。它看起来像这样,假设您的类型具有有效的 ToString 实现:

public class IPEndPointConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        IPEndPoint endPoint = (IPEndPoint)value;
        return endPoint.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

然后您可以使用 ResourceDictionary 将转换器添加到您的 XAML 文件,如下所示(假设您已经添加了相关的命名空间,这里称为 "converters",到您的 XAML) :

<Window.Resources>
    <converters:IPEndPointConverter x:Key="ipEndPointConverter" />
</Window.Resources>

然后,您只需将其添加到绑定中,即可在 XAML 中任何需要的地方使用它:

<TextBox Text="{Binding Path=EndPoint.Address, Converter={StaticResource ResourceKey=ipEndPointConverter}}" />

可用于在 IP 地址和字符串之间进行转换的转换器。

public class IPAddressConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var ipAddress = value as IPAddress;

        if (ipAddress != null)
        {
            return ipAddress.ToString();
        }

        return DependencyProperty.UnsetValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var text = value as string;
        IPAddress ipAddress;

        if (text != null && IPAddress.TryParse(text, out ipAddress))
        {
            return ipAddress;
        }

        return DependencyProperty.UnsetValue;
    }
}

然后在 ResourceDictionary 或 FrameworkElement 的 Resources 集合中

<IPAddressConverter x:Key="IpAddressConverter" />

并且在绑定中:

<TextBox Text="{Binding EndPoint.Address, Converter={StaticResource IpAddressConverter}}" />