【问题标题】:Dynamically generating ViewModel for tooltips in WPF MVVM为 WPF MVVM 中的工具提示动态生成 ViewModel
【发布时间】:2012-01-25 00:57:11
【问题描述】:

我有一个代表 MVVM 控件中包的项目列表。

当您将鼠标悬停在工具提示上时,它需要转到数据库以获取更多信息,为简单起见,我们将其称为“PackageDetails”。我知道如何使用 ViewModel 类处理数据库加载,但我无法确定何时实例化它。

方法 1) 在 'Package' 对象中有一个 'lazy-load' 属性,因此当工具提示被触发时,视图模型将被创建并立即访问数据库。 这种方法并不理想,因为每个“包”对象都不是真正的视图模型,并且最初来自 WCF 对象。

方法 2) 使用Josh Smith blog entry 中解释的转换器。他的例子似乎很适合转换器,但我认为它不太适合我的情况。

方法 3) 以某种方式在 XAML 中创建视图模型,但这似乎是个坏主意。

使用 MVVM 为工具提示动态生成视图模型的好方法是什么 ?

【问题讨论】:

    标签: wpf mvvm


    【解决方案1】:

    将模型(在您的情况下是包)绑定到视图仅适用于没有更多“处理”或业务逻辑要实现的非常简单的情况。

    我尝试了几个选项,最终为我的所有模型创建了一个 VM 包装器。沿着这条路走下去,就可以直接拥有一个工具提示属性。

    我尝试过的另一个选项是使用部分类来扩展 wcf 模型。除非您使用 dataannotations 进行验证,否则此方法有效(wcf 和 dataannotations 不能正常协同工作)

    如果您决定使用 vm 包装模型,那么使用 linq 和 lambdas 实例化您的 VM 包装器列表只是一行代码

    假设您的 VM 上有一个接受您的模型作为参数的构造函数。

    var listPackageVMs = new ObservableCollection<PackageVM> ( listPackageModels.Select(model=> new PackageVM(model)));
    

    【讨论】:

    • 谢谢我在少数情况下做过这样的事情,但在这里我有一个非常嵌套的对象:订单 > 包 > 订单项等,不想把它弄得太乱工具提示
    • 您的第二个偏好是什么。我实际上使用了一个在这种情况下似乎合适的转换器,但它仍然感觉有点不对
    • 我的第二个偏好是使用分部类,因为 WCF 将其所有模型都创建为分部类。您可以将“ToolTip”字符串属性添加到分部类,并将其绑定到 xaml 中控件的工具提示。我同意您的工具提示的转换器似乎错误
    【解决方案2】:

    您可以为 Package 创建一个部分类。我会避免将数据访问逻辑放在实体类中,但这是一种既便宜又简单的方法。

    namespace WCFServiceNamespace
    {
        // Since WCF generated entities are partial classes, we can inject features
        public partial class Package
        {
            private readonly IDataAccessor _DataAccessor;
    
            public Package()
                : this(DataAccessor.Instance) // how you choose to inject a data accessor is up to you
            {
            }
    
            public Package(IDataAccessor dataAccessor)
            {
                _DataAccessor = dataAccessor;
                _ToolTip = new Lazy<string>(GetToolTip);
            }
    
            private readonly Lazy<string> _ToolTip;
            public string ToolTip
            {
                get
                {
                    // executes GetToolTip when the Value property of Lazy<T> is accessed
                    return _ToolTip.Value;
                }
            }
    
            private string GetToolTip()
            {
                // we're assuming we can retreive the tooltip by ID, and that PackageId is defined in the generated WCF entity
                return _DataAccessor.GetToolTipByPackageId(PackageId);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 2013-07-25
      • 1970-01-01
      相关资源
      最近更新 更多