【问题标题】:UserControl update image based on datatypeUserControl 根据数据类型更新图像
【发布时间】:2012-11-02 06:57:28
【问题描述】:

我有一个显示客户、公司或员工信息的程序。我想在此图像旁边显示一个图标,该图标会根据我显示的信息类型(客户、公司或员工)而变化。

我的资源字典中有以下设置来指定图像:

<ImageSource x:Key="CompanyIcon">../Images/companies_32.png</ImageSource>
<ImageSource x:Key="EmployeeIcon">../Images/employee_32.png</ImageSource>
<ImageSource x:Key="CustomerIcon">../Images/customer_32.png</ImageSource>

在我的视图模型中,我想根据我正在使用的数据类型分配图像。例如,如果我正在查看公司的信息(使用 EF 4.5 的“Company”类型的 DBContext),我想将图像设置为“CompanyIcon”的图像。

如何将图像分配给视图模型(并在我在“公司”、“员工”或“客户”DBContext 类型之间进行更改时对其进行更改),然后将此图像绑定到视图中的占位符(它将是显示在网格列中)。

【问题讨论】:

    标签: wpf image mvvm resourcedictionary


    【解决方案1】:

    我会使用 DataTrigger 根据对象类型设置 Image.Source,并使用返回 typeof(value) 的转换器来获取类型

    <Style x:Key="MyStyle" TargetType="{x:Type Image}">
        <!-- Default Value -->
        <Setter Property="Source" Value="{StaticResource CompanyIcon}" />
    
        <Style.Triggers>
            <DataTrigger Binding="{Binding Converter={StaticResource ObjectToTypeConverter}}" 
                         Value="{x:Type local:Employee}">
                <Setter Property="Source" Value="{StaticResource EmployeeIcon}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Converter={StaticResource ObjectToTypeConverter}}" 
                         Value="{x:Type local:Customer}">
                <Setter Property="Source" Value="{StaticResource CustomerIcon}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
    

    我通常使用的转换器是这样的:

    public class ObjectToTypeConverter : IValueConverter
    {
        #region IValueConverter Members
    
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return null;
    
            return value.GetType();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    
        #endregion
    }
    

    【讨论】:

    • 谢谢。你能告诉我 Style 是否存储在 ResourceDictionary 中吗?那么我将如何在网格布局中实现这种风格呢?
    • @BrianKE 样式可以放置在 XAML 中的任何 &lt;FrameworkElement.Resources&gt; 标记中,例如 &lt;UserControl.Resources&gt;&lt;Window.Resources&gt;,或 ResourceDictionary,然后您必须使您的 @ 987654330@应用样式,如&lt;Image Style="{DynamicResource MyImageStyle}"&gt;
    【解决方案2】:

    我所做的是在 VM 中有一个指向图像位置的字符串属性(不知道这是否是最好的方法,但它对我来说效果很好):

    private string _imageSource;
    public string ImageSource 
    {
       get
       {
         return _imageSource;
       }
       set
       {
          _imageSource = value;
          NotifyPropertyChanged(() => ImageSource);
       }
    
    }
    
    public void SetImage()
    {
        If (customer)
            ImageSource = "../Images/companies_32.png";
        ...
    }
    

    在 XAML 中:

    <Image Source="{Binding ImageSource}" .../>
    

    【讨论】:

    • 在 vm 中执行此操作的问题在于,您不必要地模糊了关注点的分离,这只能作为最后的手段。不尊重关注点的分离将导致臃肿和脆弱的视图模型。图像显示是一个 View 关注点,在这种情况下,一旦您知道如何处理,View 就可以轻松处理它。干杯
    • @Berryl 这是真的。你会建议如何处理这个问题?
    • 在这种特殊情况下,您需要按类型更改一个控件的图像?实际上,我喜欢这里介绍的 Rachel 的解决方案。 Here is another 示例说明如何使用 DataTemplates 和隐式数据类型实现更复杂的类型渲染切换。
    • FWIW 我也曾经尝试将这样的东西塞进我的视图模型中!似乎是个好主意,直​​到我发现我的视图模型不必要地臃肿和脆弱......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-24
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多