应用界面美化工具DevExpress WPF使用教程:绑定到列集合

下载DevExpress v20.2完整版

DevExpress技术交流群3:700924826      欢迎一起进群讨论

DevExpress WPF 拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。

使用模型视图ViewModel(MVVM)架构模式设计WPF应用程序时,可能需要描述模型或ViewModel中的列。 网格可以绑定到包含列设置的对象集合,该对象设置在Model或ViewModel中进行了描述,从而最大限度地减少了“隐藏代码”的需求。

实现视图模型

假设一个雇员视图模型,它包括以下类:

  • Employee - 包含员工信息(例如名字和姓氏,职务等)的数据对象。
  • ViewModel - 员工视图模型。
  • EmployeeData - 提供要在网格控件中显示的员工信息。
  • Column - 描述网格列,此类提供的属性对应于所有类型的网格列的通用设置。
  • ComboBoxColumn - 对应于ComboBoxEdit in-place编辑器的网格列,此类提供Source属性,其中包含组合框项目的列表(在此示例中,这些城市)。
  • SettingsType - 枚举用于编辑单元格值的in-place编辑器的可能类型。

C#

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace Model {
public class ViewModel {
public List<string> Cities { get; private set; }
// Returns a list of employees so that they can be bound to the grid control.
public List<Employee> Source { get; private set; }
// The collection of grid columns.
public ObservableCollection<Column> Columns { get; private set; }
public ViewModel() {
Source = EmployeeData.DataSource;
List<string> _cities = new List<string>();
foreach (Employee employee in Source) {
if (!_cities.Contains(employee.City))
_cities.Add(employee.City);
}
Cities = _cities;
Columns = new ObservableCollection<Column>() {
new Column() { FieldName = "FirstName", Settings = SettingsType.Default },
new Column() { FieldName = "LastName", Settings = SettingsType.Default },
new Column() { FieldName = "JobTitle", Settings = SettingsType.Default },
new Column() { FieldName = "BirthDate", Settings = SettingsType.Default },
new ComboColumn() { FieldName = "City", Settings = SettingsType.Combo, Source = Cities }
};
}
}
// The data item.
public class Employee {
public string FirstName { get; set; }
public string LastName { get; set; }
public string JobTitle { get; set; }
public string City { get; set; }
public DateTime BirthDate { get; set; }
}
public class EmployeeData : List<Employee> {
public static List<Employee> DataSource {
get {
List<Employee> list = new List<Employee>();
list.Add(new Employee() {
FirstName = "Nathan",
LastName = "White",
City = "NY",
JobTitle = "Sales Manager",
BirthDate = new DateTime(1970, 1, 10) });
return list;
}
}
}
public class Column {
// Specifies the name of a data source field to which the column is bound.
public string FieldName { get; set; }
// Specifies the type of an in-place editor used to edit column values.
public SettingsType Settings { get; set; }
}
// Corresponds to a column with the combo box in-place editor.
public class ComboColumn : Column {
// The source of combo box items.
public IList Source { get; set; }
}
public enum SettingsType { Default, Combo }
}

 

注意:如果将Columns集合分配给网格控件后可能会更改,则它应实现INotifyCollectionChanged,以便网格中可自动反映View Model内所做的更改。

列模板和选择器

网格控件基于列模板生成列,创建多个模板,每种列类型一个模板。使用单个模板,您可以在无限数量的网格控件中创建无限数量的列。 在此示例中,有两个列模板:DefaultColumnTemplateComboColumnTemplate

为避免绑定到列属性时的性能问题,请使用dxci:DependencyObjectExtensions.DataContext附加属性,请参见下面的示例。

XAML

 

<!---->
xmlns:dxci="http://schemas.devexpress.com/winfx/2008/xaml/core/internal"
<!---->
<DataTemplate x:Key="DefaultColumnTemplate">
<ContentControl>
<dxg:GridColumn FieldName="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}"
Header="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).Header, RelativeSource={RelativeSource Self}}"
Width="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).Width, RelativeSource={RelativeSource Self}}" />
</ContentControl>
</DataTemplate>

 

要根据列的类型选择所需的模板,请使用模板选择器。 在此示例中,模板选择器由ColumnTemplateSelector类表示。

XAML

 

<Window x:Class="WpfApplication10.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxci="http://schemas.devexpress.com/winfx/2008/xaml/core/internal"
xmlns:model="clr-namespace:Model"
xmlns:view="clr-namespace:View">
<Window.DataContext>
<model:ViewModel/>
</Window.DataContext>
<Window.Resources>
<view:ColumnTemplateSelector x:Key="ColumnTemplateSelector"/>
<DataTemplate x:Key="DefaultColumnTemplate">
<ContentControl>
<dxg:GridColumn FieldName="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}"/>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="ComboColumnTemplate">
<ContentControl>
<dxg:GridColumn FieldName="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}">
<dxg:GridColumn.EditSettings>
<dxe:ComboBoxEditSettings ItemsSource="{Binding Source}"/>
</dxg:GridColumn.EditSettings>
</dxg:GridColumn>
</ContentControl>
</DataTemplate>
</Window.Resources>
<Grid>
</Grid>
</Window>

 

C#

 

using System.Windows;
using System.Windows.Controls;
using Model;

namespace View {
public class ColumnTemplateSelector : DataTemplateSelector {
public override DataTemplate SelectTemplate(object item, DependencyObject container) {
Column column = (Column)item;
return (DataTemplate)((Control)container).FindResource(column.Settings + "ColumnTemplate");
}
}
}

 

注意:如果可以使用单个模板描述所有网格列,则无需创建列模板选择器,而是将此模板分配给网格的DataControlBase.ColumnGeneratorTemplate属性。

注意:您可以创建一种样式来指定使用不同模板生成的所有列共有的设置,您可以在样式内指定对ViewModel属性的绑定(请参见下面的FieldName):

XAML

 

<Window.Resources>
<Style x:Key="ColumnStyle" TargetType="dxg:GridColumn">
<Setter Property="FilterPopupMode" Value="CheckedList"/>
<Setter Property="FieldName" Value="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}"/>
</Style>
</Window.Resources>

 

该样式应分配给DataControlBase.ColumnGeneratorStyle属性。

自定义WPF DXGrid

最后,指定网格的DataControlBase.ItemsSourceDataControlBase.ColumnsSourceDataControlBase.ColumnGeneratorTemplateSelectorDataControlBase.ItemsSource属性指定网格的数据源,DataControlBase.ColumnsSource属性指定网格从中生成列的源,DataControlBase.ColumnGeneratorTemplateSelector属性指定列模板选择器,该选择器根据其类型为每个列返回一个模板。

XAML

 

<Grid>
<dxg:GridControl Name="grid"
ItemsSource="{Binding Source}"
ColumnsSource="{Binding Columns}"
ColumnGeneratorTemplateSelector="{StaticResource ColumnTemplateSelector}">
<dxg:GridControl.View>
<dxg:TableView Name="tableView1"
AutoWidth="True"
NavigationStyle="Cell" />
</dxg:GridControl.View>
</dxg:GridControl>
</Grid>

 

下图显示了结果。

界面开发控件DevExpress WPF使用教程


上DevExpress中文网,获取第一手最新产品资讯!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ModernUI(http://mui.codeplex.com/)是一个开源的WPF界面库,利用该界面库,我们可以创建很酷的应用程序。下面是ModernUI官方示例,你可以从官方网站直接下载源码运行,如果是.NET 4.0的话,记得要声明“NET4”预编译变量,否则无法编译通过。 这个界面框架是基于ModernUI来实现的,在该文我将分享所有的源码,并详细描述如何基于ModernUI来构造一个非常通用的、插件化的WPF开发框架。下载源码的同志,希望点击一下推荐。 本文将按照以下四点来介绍: (1)ModernUI简介; (2)构建通用界面框架的思路; (3)基于ModernUI和OSGi.NET的插件化界面框架实现原理及源码分析; (4)其它更有趣的东西~~。 要编写这样的WPF界面,我们需要在一个Window上声明菜单和Tab页面,下图是定义菜单的声明。 此外,每一个Tab风格页面,你也需要手动的为菜单创建这样的界面元素。 直接用这样的方式来使用ModernUI,显然不太适合团队协作性的并行开发,因为在一个团队的协作中,不同的人需要完成不同的功能,实现不同页面,每个人都需要来更改主界面。 我非常希望模块化的开发方法,因为这可以尽可能的复用现有资产,使程序员可以聚焦在自己关注的业务逻辑上,不需要关心UI的使用。下面,我将来描述基于ModernUI实现的一个通用界面框架,这个界面框架允许程序员在自己的业务模块中配置需要显示的界面元素。 通用界面框架实现思路: 我希望能够实现这样的通用界面框架: (1)程序员可以直接实现需要展现业务逻辑的界面,不需要关注如何使用ModernUI; (2)程序员可以通过简单的配置就可以将自己实现的业务逻辑页面显示在主界面中; (3)这个界面框架可以完全复用。 当我看到ModernUI这个界面库时,我希望将应用程序做成模块化,每一个模块能够: (1)通过以下配置能够直接显示二级菜单。 (2)通过以下配置能够直接显示三级菜单。 这样做的好处是,开发插件的时候可以不需要关心界面框架插件;团队在协作开发应用的时候,可以独立开发并不需要修改主界面;团队成员的插件可以随时集成到这个主界面;当主界面无法满足我们的布局时或者用户需求无法满足时,可以直接替换主界面框架而不需要修改任何插件代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值