我要将旧的WinForms应用程序重做为WPF应用程序。该应用程序的核心是自定义“网格”组件。我想了解一下作为WPF组件的最佳方法。
应用程序显示不同国家/部门的数据网格。网格的每个单元格根据该国家/部门的可用数据显示不同的信息(例如图形,图像)。
我有一个我希望保持清洁的域模型程序集 - 以最大限度地重用。结构如下:
网格显示左下角的国家和顶部的扇区。
在当前应用程序中,网格组件具有(POCO)表属性和用于手动重绘的Refresh()方法。因此,如果更新了表,则网格组件的父级会刷新它。如果单击一个洲,国家或单元格,网格组件还会触发许多事件,以便父级可以使用弹出菜单进行响应等。
一切正常。
但是,我想知道这是否是用于WPF应用程序的正确模型。看看许多WPF示例,它们支持数据绑定等。但是,从简单的示例来看,我不清楚如何将复杂对象绑定到我的组件 - 或者它是否值得。
此外,WinForms组件是完全自定义绘制的 - 没有使用子控件(例如标签)。使用WPF用户控件并从GridLayout和许多Label,Shape等控件构建表会更好吗?在实践中,它们可能在网格中有20行和20列,并且用户在使用应用程序时会定期删除并添加国家/扇区(行/列)。
我的直接目标是确保我的设计在WPF生态系统中发挥出色,但我的第二个目标是学习如何以WPFy方式做事 - 鉴于这是我的第一个WPF应用程序。我非常关注构建一个普通的WPF应用程序 - 它只是自定义控件的东西仍然有点模糊(甚至在阅读它之后)。
任何见解/指导都将不胜感激。
答案 0 :(得分:1)
您肯定希望调整MVVM方法,如outlined by Josh Smith。实际上,这意味着您的自定义网格组件将包含在它自己的视图中。支持视图将是您的ViewModel,您将在其中定义包含数据的对象的ObservableCollection。这些对象可能来自您的模型。这种互动如下所示:
<强>型号:强>
public class TableData
{
public string Country { get; set; }
public string Continent { get; set; }
public object Sector { get; set; }
}
public class TableManager : ITableManager
{
public Collection<TableData> Rows;
public void GetData()
{
this.Rows = new Collection<TableData>();
this.Rows.Add(...
}
}
<强>视图模型:强>
public class TableViewModel
{
private ITableManager _tableManager;
public TableViewModel() : base(new TableManager())
{
}
// for dependency injection (recommended)
public TableViewModel(ITableManager tableManager)
{
_tableManager = tableManager;
_tableManager.GetData();
}
public ObservableCollection<TableData> Rows
{
get { return _tableManager.Rows; }
}
}
查看:强>
<ctrls:CustomDataGrid
ItemsSource={Binding Rows}
AutoGenerateColumns=True
>
<!-- Use AutoGenerateColumns if the # of sectors is dynamic -->
<!-- Otherwise, define columns manually, like so: -->
<DataGridTextColumn
Width="*"
Header="SectorA"
Binding="{Binding Country}
/>
</ctrls:CustomDataGrid>
我在视图中使用了CustomDataGrid
,因为我假设您要将自己的DataGrid子类化。这将允许您覆盖事件以根据自己的喜好自定义DataGrid:
public class CustomDataGrid : DataGrid
{
public override Event...
}