创建自定义WPF控件时应该使用什么方法?

创建自定义WPF控件时应该使用什么方法?,wpf,data-binding,custom-controls,Wpf,Data Binding,Custom Controls,我将把一个旧的WinForms应用程序作为WPF应用程序重做。该应用程序的核心是一个定制的“网格”组件。我想知道作为WPF组件实现这一点的最佳方法 该应用程序显示不同国家/部门的数据网格。网格的每个单元格显示不同的信息(例如图形、图像),具体取决于该国家/地区的可用数据 我有一个域模型程序集,我想保持干净-以最大限度地重用。结构如下: 桌子 大陆 国家 部门 数据[国家、部门] 该网格在左下方显示国家,在顶部显示行业 在当前应用程序中,网格组件有一个(POCO)表属性和一个Refresh

我将把一个旧的WinForms应用程序作为WPF应用程序重做。该应用程序的核心是一个定制的“网格”组件。我想知道作为WPF组件实现这一点的最佳方法

该应用程序显示不同国家/部门的数据网格。网格的每个单元格显示不同的信息(例如图形、图像),具体取决于该国家/地区的可用数据

我有一个域模型程序集,我想保持干净-以最大限度地重用。结构如下:

  • 桌子
    • 大陆
    • 国家
    • 部门
    • 数据[国家、部门]
该网格在左下方显示国家,在顶部显示行业

在当前应用程序中,网格组件有一个(POCO)表属性和一个Refresh()方法来手动重新绘制它。因此,如果表被更新,网格组件的父级将刷新它。网格组件还有许多事件,如果单击某个大陆、国家或单元格,就会触发这些事件,以便父级可以使用弹出菜单等进行响应

这一切都很好

但是,我想知道这是否是用于WPF应用程序的正确模型。查看许多WPF示例,它们支持数据绑定等。但是,从简单的示例来看,不清楚如何将复杂对象绑定到组件,或者是否值得

此外,WinForms组件完全是自定义绘制的-没有正在使用的子控件(例如标签)。使用WPF用户控件并从GridLayout和大量Label、Shape等控件构建表是否更好?实际上,网格中可能有20行和20列,用户在使用应用程序时会定期删除和添加国家/地区(行/列)

我的近期目标是确保我的设计在WPF生态系统中发挥良好作用,但我的第二个目标是学习如何以WPFy的方式做事——这是我的第一个WPF应用程序。我非常了解如何构建一个通用的WPF应用程序——它只是一些自定义控件的东西,仍然有点模糊(即使在阅读了一些相关内容之后)


如有任何见解/指导,将不胜感激

您肯定希望采用MVVM方法,如图所示。实际上,这意味着您的自定义网格组件将包含在它自己的视图中。支持视图的是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>

现有控件的映像将有所帮助。
public class CustomDataGrid : DataGrid
{
    public override Event... 
}