WPF MVVM可以替代IValueConverter

时间:2014-06-25 13:26:11

标签: c# wpf mvvm

我有几组Observable项目集合,这些项目在后台线程上定期更新(30到60秒)。这些集合通过View上的ItemsControls显示。父控件和控件中的项目具有与每个项目的状态相关联的多个显示属性。

  1. 状态将决定文本旁边显示的形状以及该形状的笔触和填充颜色。
  2. 状态将确定该项目文本的背景颜色和文本颜色。
  3. 状态将确定项目中是否显示倒数计时器(计时器与视图模型没有关系)
  4. 状态可以确定父容器的边框颜色。
  5. 我目前正在为每个属性在各个IValueConverters中执行此逻辑。它有效,但感觉很麻烦并且散开。我几乎想以某种方式订阅UI中的PropertyChanged事件并让它调用一个方法来呈现该项的所有显示,以便所有逻辑都包含在一个地方。有更好的方法可以做到这一点,还是应该坚持使用IValueConverters?

    这是我的一个例子。

    收藏品:

    public ObservableCollection<PanelItem> PanelItems1 
    {
        get { return panelItems1; }
        set
        {
            panelItems1 = value;
            base.OnPropertyChanged("PanelItems1");
        }
    }
    

    PanelItem是一小组属性,包括:名称,值(状态),描述。 ItemsControls类似于以下内容:

    <Border Grid.Row="0" Grid.Column="0"
            BorderBrush="{Binding Path=PanelGroup1.HighestStatus, Converter={StaticResource ParentBorderColorConverter}}"
            BorderThickness="3" Height="Auto" Width="Auto" Margin="0,0,2,0">
        <StackPanel Grid.Column="0" Grid.Row="0">
            <Label Grid.Row="0" Grid.Column="0" Content="First Group" Style="{StaticResource panelTitle}" />
            <ItemsControl ItemsSource="{Binding Path=PanelItems1, Mode=TwoWay}"
                          ItemTemplate="{StaticResource PanelItemTemplate}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel IsItemsHost="True" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
    
            <!-- Here is the Data Template -->
            <DataTemplate x:Key="PanelItemTemplate">
                <Viewbox MaxHeight="20" HorizontalAlignment="Left" Cursor="Hand">
                    <WrapPanel>
                        <Path Margin="2,2,2,2" StrokeThickness="2">
                            <Path.Data>
                                <Binding Path="Status" Mode="OneWay" Converter="{StaticResource ShapeConverter}" />
                            </Path.Data>
                            <Path.Fill>
                                <Binding Path="Status" Mode="OneWay" Converter="{StaticResource ShapeColorConverter}" />
                            </Path.Fill>
                            <Path.Stroke>
                                <Binding Path="Status" Mode="OneWay" Converter="{StaticResource ShapeBorderConverter}" />
                            </Path.Stroke>
                        </Path>
                        <ContentPresenter Content="{Binding Path=Name}" Margin="5,0,0,0" />
                    </WrapPanel>
                </Viewbox>
            </DataTemplate>
        </StackPanel>
    </Border>
    

2 个答案:

答案 0 :(得分:2)

为什么不直接声明为INotifyPropertyChanged对象实现Status接口的普通类?只需在其中添加所需的属性,例如GeometryFillStroke等等...如果您这样做,则不需要任何Converter课程,你可以做这样的事情:

<DataTemplate x:Key="PanelItemTemplate">
    <Viewbox MaxHeight="20" HorizontalAlignment="Left" Cursor="Hand" > 
           <WrapPanel>
                <Path Margin="2,2,2,2" StrokeThickness="2" >
                <Path.Data>
                    <Binding Path="Status.Geometry" Mode="OneWay" />
                </Path.Data>
                <Path.Fill>
                    <Binding Path="Status.Fill" Mode="OneWay" />
                </Path.Fill>
                <Path.Stroke>
                    <Binding Path="Status.Stroke" Mode="OneWay" />
                </Path.Stroke>
            </Path>
            <ContentPresenter  Content="{Binding Path=Name}" Margin="5,0,0,0"   />
        </WrapPanel>
    </Viewbox>
</DataTemplate>

答案 1 :(得分:0)

可以只创建一个包含所有转换逻辑的转换器,并返回一个将绑定到的新类:

public class MyNewConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Perform all required conversions here and return them as a new type of object
        return new
            {
                Data = ...,
                Fill = ...,
                Stroke = ...
            };
    }
}

然后您需要做的就是修改Path的{​​{1}}属性以使用此转换器。

DataContext