【问题标题】:How to design this using WPF bindings如何使用 WPF 绑定进行设计
【发布时间】:2011-02-23 20:14:45
【问题描述】:

我有一个'tickets'列表,它们都派生自抽象类TicketBase

public abstract class TicketBase
{
     public DateTime PublishedTime { get; set; }
     public String TicketType { get; set; }
}

public class TicketA : TicketBase
{
     public string PropertyA { get; set; }
}

public class TicketB : TicketBase
{
     public string PropertyB { get; set; }
}

在我的主视图模型中,我查询数据库并返回 List<TicketBase> Tickets,按 PublishedTime 升序排列。

在我看来,我想要这样的东西:

Property A: <most recent value of PropertyA> 
Property B: <most recent value of PropertyB>

所以我想有一个SummaryViewModel,我可以绑定到它具有如下属性:

public string LatestPropertyA { get; set; }
public string LatestPropertyB { get; set; }

在这些属性的设置器中,只需对 Tickets 集合执行 linq 查询,该集合会获取最顶层的票证,其中 TicketType 是相关类型并获得适当的属性。

有没有一种方法可以将 TicketType 作为绑定的一部分传递,还是需要在每个 setter 方法中硬编码类型?

另外,这是这种绑定方式的最佳方法吗,有没有更好的方法使用我不熟悉的 WPF 绑定的某些功能?

【问题讨论】:

    标签: wpf data-binding binding


    【解决方案1】:

    您的基类不应依赖于任何派生自它的子类,因此请删除 TicketType 并使用 is 运算符来确定 TicketBase 实例的确切类型。将工单加载到工单集合中,并使用 XAML 中定义的常规数据绑定从视图中访问它们。下面的示例代码向您展示了如何编写使用 linq 的属性。

    另一种方法是使用值转换器和数据绑定到工单。您将类型和属性名称作为参数传递,并在值转换器中使用反射返回正确的属性值。

    public class VM
    {
        public VM()
        {
            Tickets = DB.LoadTicketsSorted();    
        }
    
        public string LatestPropertyA { get { return Tickets.Where(t => t is TicketA).Select(t => (t as TicketA).PropertyA).FirstOrDefault(); } }
        public string LatestPropertyB { get { return Tickets.Where(t => t is TicketB).Select(t => (t as TicketB).PropertyB).FirstOrDefault(); } }
    
        private List<TicketBase> Tickets;
    
    }
    

    【讨论】:

    • 不是对答案有效性的评论,而是吸气剂的替代方案。这将是使用内置 Linq 过滤器 OfType 并减少子句数量的好案例:Tickets.OfType&lt;TicketA&gt;().FirstOrDefault().PropertyA
    • 再一次,如果FirstOrDefault 返回 null,你会收到 NullReferenceException。
    猜你喜欢
    • 1970-01-01
    • 2011-01-19
    • 2019-05-20
    • 2021-11-16
    • 2015-01-20
    • 1970-01-01
    • 2011-03-21
    • 2011-06-16
    相关资源
    最近更新 更多