为了账号安全,请及时绑定邮箱和手机立即绑定

使用 MVVM 在模型外计算和查看列

使用 MVVM 在模型外计算和查看列

C#
慕慕森 2022-11-21 15:43:35
我需要使用 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 旁边的图像。如果订单下的所有 orderitems 都已交付 ( Delivered=1 ),则应使用 picture1,否则使用 picture2。所以我有约束力ObservableCollection<Order>。模型是使用实体框架(首先是数据库)从 .tt 生成的,因此由于可能的数据库更新,将计算直接放入 Order.cs 类是个坏主意。我的第一个想法是使用MSSQL Computed column,但我认为这不是一个好的方法(解决方案中可能有很多这样的情况),因此模型会非常庞大和复杂。第二个想法是使用转换器,但它应该用于简单的任务,而不是用于计算逻辑(这是)。第三个想法是改变并ObservableCollection<Order>以ObservableCollection<Tuple<string,Order>>某种方式将其绑定到一个视图,但是......你知道,这是一个坏主意。所以我的问题很简单。我如何使用 MVVM 最佳实践解决这个问题(在哪里放置此目的的计算逻辑)。谢谢。
查看完整描述

1 回答

?
婷婷同学_

TA贡献1844条经验 获得超8个赞

好吧,在谷歌搜索之后,我决定创建这个解决方案。也许它会对某人有所帮助。首先,我创建了 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>

最后是视觉效果。

//img1.sycdn.imooc.com//637b2c560001cf3502240105.jpg

查看完整回答
反对 回复 2022-11-21
  • 1 回答
  • 0 关注
  • 141 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号