锁定数据绑定MVVM

时间:2015-05-05 14:10:01

标签: c# wpf mvvm binding

我有一个带有Image组件的表单。我想在运行时加载图像。 在我的ViewModel中,我有一个表示图像源路径的属性:

public string ImagePath { get; set; }

此属性绑定到我的ImageComponent的 Source 。 问题是,当我启动应用程序时,ImagePath为null,默认转换器尝试将 ImagePath 转换为 System.Windows.Media.ImageSource 并引发异常。< / p>

我想到了3个解决方案:
  - 创建自定义转换器(当字符串为空时可以提供默认的ImageSource)
  - 阻止视图获取ImagePath(不知道如何)
  - 使用System.Windows.Media.ImageSource代替字符串。 (不确定MVVM模式是否满足,因为System.Windows.Media仅由视图使用)

所以我的问题是:哪个解决方案更好(不仅仅是我的3个)以及实施方案是什么?

XAML绑定:

 <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
      <Image Name="image" Stretch="Uniform" Source="{Binding Main.ImagePath, Mode=OneWay, Source={StaticResource Locator}}" />
 </ScrollViewer>

提出异常:

System.Windows.Data Error: 23 : Cannot convert '' from type 'String' to type 'System.Windows.Media.ImageSource' for 'en-US' culture with default conversions;

2 个答案:

答案 0 :(得分:2)

正如我在之前的评论中所说,您不需要自定义转换器来管理空值。您可以在源代码的绑定中使用TargetNullValue

<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
  <Image Name="image" Stretch="Uniform" Source="{Binding Main.ImagePath, TargetNullValue={x:Null}, Mode=OneWay, Source={StaticResource Locator}}" />
</ScrollViewer>

此外,如果您愿意,可以在TargetNullValue中指定默认路径。

答案 1 :(得分:-1)

我刚刚启动了一个vanilla MVVM Light项目(.NET 4.5),并在我的代码中添加了以下内容,但我没有得到您所描述的错误。

<强> MainViewModel:

public class MainViewModel : ViewModelBase
{
    public string ImagePath
    {
        get
        {
            return _imagePath;
        }
        set
        {
            _imagePath = value;
            RaisePropertyChanged(() => ImagePath);
        }
    }
    private string _imagePath;

    public RelayCommand ImageCommand
    {
        get
        {
            return _imageCommand ??
                (_imageCommand = new RelayCommand(() => ImagePath = "Image.png"));
        }
    }
    private RelayCommand _imageCommand ;

    public MainViewModel()
    {
        // I've tried both of those and it still works
        //ImagePath = "";
        //ImagePath = null;
    }
}

MainWindow内容XAML:

<StackPanel>
    <ScrollViewer HorizontalScrollBarVisibility="Auto"
                  VerticalScrollBarVisibility="Auto">
        <Image x:Name="TestImage"
               Source="{Binding Main.ImagePath,
                                Mode=OneWay,
                                Source={StaticResource Locator}}"
               Stretch="Uniform" />
    </ScrollViewer>

    <Button Command="{Binding Main.ImageCommand,
                              Source={StaticResource Locator}}"
            Content="Click" />
</StackPanel>