【问题标题】:Computing and viewing column outside model using MVVM使用 MVVM 计算和查看模型外的列
【发布时间】:2019-08-21 11:04:38
【问题描述】:

我需要使用 C# MVVM 解决以下问题。我正在使用以下模型。

我的一个 UserControls 得到了以下 ListBox 模板。

<ListBox ItemsSource="{Binding OrdersListViewViewModel.AllItems, Source={StaticResource Locator}}" SelectedItem="{Binding OrdersListViewViewModel.SelectedItem, Source={StaticResource Locator}}" Background="White">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal" Margin="0 0 0 0" Height="Auto" Width="Auto" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel  Margin="0,7,0,6" HorizontalAlignment="Left" Orientation="Horizontal">
            <Image Width="25" Height="25" Margin="5 2 0 0" Source="{Binding OrdersListViewViewModel.OrderDeliveryStateImage, Mode=OneWay, Source={StaticResource Locator}}"/>
            <TextBlock Margin="25,5,25,5"  Text="{Binding OrdersListViewViewModel.AllItems/Customer.CustomerName, FallbackValue=N/A, Mode=OneWay, Source={StaticResource Locator}}" FontSize="20"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

列表显示从数据库加载的所有订单(客户名称)。我想用图片填充的 TextBlock 旁边的图像。如果订单下的所有订单商品都已发货(Delivered=1),则应使用图片1,否则使用图片2。

所以我绑定ObservableCollection&lt;Order&gt;。模型是使用实体框架(db first)从 .tt 生成的,因此将计算直接放入 Order.cs 类是个坏主意,因为可能会更新 db。

我的第一个想法是使用 MSSQL Computed 列,但我认为这不是一个好的方法(解决方案中可能有很多这样的情况),因此模型会庞大而复杂。

第二个想法是使用转换器,但它应该用于简单的任务,而不是用于计算逻辑(就是这样)。

第三个想法是将ObservableCollection&lt;Order&gt; 更改为ObservableCollection&lt;Tuple&lt;string,Order&gt;&gt; 并以某种方式将其绑定到一个视图,但是......你知道,这是个坏主意。

所以我的问题很简单。如何使用 MVVM 最佳实践解决此问题(在何处放置此目的的计算逻辑)。

谢谢。

【问题讨论】:

  • 使用数据触发器,或者在视图模型中计算出来

标签: c# sql-server entity-framework-6 mvvm-light computation


【解决方案1】:

经过谷歌搜索后,我决定创建此解决方案。也许它会对某人有所帮助。 首先,我创建了 Order 实体的部分类以分隔文件,因此当实体框架更新 Order 实体时,它不会覆盖我的自定义设置。

然后我创建了确定订单是否已交付的自定义属性。所以计算逻辑仍然停留在模型中。

  public partial class Order
    {
        public bool IsOrderDelivered
        {
            get
            {
                int orderDelivered = 1;
                foreach (var orderItem in this.OrderItems)
                {
                    orderDelivered = orderDelivered * orderItem.Delivered;
                }
                return orderDelivered == 1 ? true : false;
            }
        }

    }

然后我创建了转换器,它只是将布尔值转换为文本,这就是它存在的原因并且使用正确。

public class OrderStatusToImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value == true ? @"Skins\approved.png" : @"Skins\denied.png";
        }

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

并在部分类中与转换器一起在我的新属性上创建了数据绑定。

       <StackPanel  Margin="0,7,0,6" HorizontalAlignment="Left" Orientation="Horizontal">
                    <Image Width="25" Height="25" Margin="5 2 0 0" Source="{Binding IsOrderDelivered, Converter={StaticResource OrderStatusToImageConverter}, Mode=OneWay}"/>
                    <TextBlock Margin="25,5,25,5"  Text="{Binding Customer.CustomerName, FallbackValue=N/A, Mode=OneWay}" FontSize="20"/>
       </StackPanel>

最后是视觉效果。

【讨论】:

    猜你喜欢
    • 2011-01-29
    • 2010-11-17
    • 2011-01-11
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多