DevExpress WPF 擁有120+個控件和庫,將幫助您交付滿足甚至超出企業需求的高性能業務應用程序。通過DevExpress WPF能創建有着強大互動功能的XAML基礎應用程序,這些應用程序專注於當代客戶的需求和構建未來新一代支持觸摸的解決方案。
使用模型視圖ViewModel(MVVM)架構模型設計WPF應用程序時,可能需要在模型或視圖模型中描述條件格式設置規則。 網格可以綁定到包含條件格式化規則的對象集合,這些條件在Model或ViewModel中進行了描述,從而最大限度地減少了“隱藏代碼”的需求。
View模型實現
本文中使用的示例包含一個視圖模型代碼,其中包括以下類。
- Order - 包含訂單信息(例如數量,折扣等)的數據對象。
- ViewModel - 訂單視圖模型,ViewModel公開Orders屬性(在網格內顯示的訂單列表)和Rules屬性(格式規則列表)。
- OrderData - 提供要在網格控件中顯示的訂單信息。
- FormattingRule - 描述條件格式設置規則,此類提供的屬性與所有類型的條件格式設置規則通用的設置相對應。
- FormattingType - 枚舉應用格式的可能類型。
C#
using System.Collections.Generic; using System.Windows; using System.Windows.Controls; namespace GridDemo { // ... public class ViewModel { public ViewModel() { Orders = GetOrders(); Rules = GetFormattingRules(); } private static List<FormattingRule> GetFormattingRules() { var rules = new List<FormattingRule>(); rules.Add(new FormattingRule() { Expression = "([UnitPrice] * [Quantity] * (1 - [Discount]) - [Freight]) < 0", ApplyToRow = true, Type = FormattingType.Background }); rules.Add(new FormattingRule() { FieldName = "Discount", Expression = "[Discount] > 0", ApplyToRow = false, Type = FormattingType.Font }); rules.Add(new FormattingRule() { FieldName = "Discount", Expression = "[Discount] > 0", Type = FormattingType.Icon }); return rules; } private static List<Order> GetOrders() { List<Order> list = new List<Order>(); list.Add(new Order() { City = "Aachen", UnitPrice = 10, Quantity = 20, Discount = 0, Freight = 30.54 }); // ... return list; } // A list of orders displayed within the grid control. public List<Order> Orders { get; private set; } // A list of conditional formatting rules. public List<FormattingRule> Rules { get; private set; } } // Corresponds to an order items displayed within grid. public class Order { public string City { get; set; } public double Discount { get; set; } public double Freight { get; set; } public double Quantity { get; set; } public double UnitPrice { get; set; } } public enum FormattingType { Icon, Font, Background } public class FormattingRule { public virtual bool ApplyToRow { get; set; } public virtual string Expression { get; set; } public virtual string FieldName { get; set; } public virtual FormattingType Type { get; set; } } }
注意:如果在將格式條件集合分配給網格控件之後可能對其進行了更改,則它應實現INotifyCollectionChanged,以便網格中可以自動反映在視圖模型內進行的更改。
格式化條件模板和選擇器
GridControl基於條件格式模板生成條件格式。 創建多個模板,每種條件格式類型一個模板。 使用單個模板,您可以在無限數量的網格控件中創建無限數量的條件格式。 在此示例中,存在三種條件格式模板:FontFormat、BackgroundFormat和IconFormat。
爲避免綁定到列屬性時的性能問題,請使用dxci:DependencyObjectExtensions.DataContext附加屬性。 請參見下面的示例。
XAML
<!----> xmlns:dxci="http://schemas.devexpress.com/winfx/2008/xaml/core/internal" <!----> <DataTemplate x:Key="FontFormat"> <ContentControl> <dxg:FormatCondition ApplyToRow="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).ApplyToRow, RelativeSource={RelativeSource Self}}" Expression="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).Expression, RelativeSource={RelativeSource Self}}" FieldName="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}"> <dxg:FormatCondition.Format> <dx:Format FontWeight="Bold" /> </dxg:FormatCondition.Format> </dxg:FormatCondition> </ContentControl> </DataTemplate>
要根據列的類型選擇所需的模板,請使用模板選擇器。 在此示例中,模板選擇器由FormatConditionSelector類表示。
XAML
<Window x:Class="GridDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:GridDemo" xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxci="http://schemas.devexpress.com/winfx/2008/xaml/core/internal" xmlns:dxt="http://schemas.devexpress.com/winfx/2008/xaml/core/themekeys" Height="350" Width="525" mc:Ignorable="d" Title="MainWindow"> <Window.DataContext> <local:ViewModel /> </Window.DataContext> <Grid> <Grid.Resources> <DataTemplate x:Key="FontFormat"> <ContentControl> <dxg:FormatCondition ApplyToRow="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).ApplyToRow, RelativeSource={RelativeSource Self}}" Expression="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).Expression, RelativeSource={RelativeSource Self}}" FieldName="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}"> <dxg:FormatCondition.Format> <dx:Format FontWeight="Bold" /> </dxg:FormatCondition.Format> </dxg:FormatCondition> </ContentControl> </DataTemplate> <DataTemplate x:Key="BackgroundFormat"> <ContentControl> <dxg:FormatCondition ApplyToRow="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).ApplyToRow, RelativeSource={RelativeSource Self}}" Expression="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).Expression, RelativeSource={RelativeSource Self}}" FieldName="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}"> <dxg:FormatCondition.Format> <dx:Format Background="LightPink" /> </dxg:FormatCondition.Format> </dxg:FormatCondition> </ContentControl> </DataTemplate> <DataTemplate x:Key="IconFormat"> <ContentControl> <dxg:FormatCondition ApplyToRow="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).ApplyToRow, RelativeSource={RelativeSource Self}}" Expression="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).Expression, RelativeSource={RelativeSource Self}}" FieldName="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).FieldName, RelativeSource={RelativeSource Self}}"> <dxg:FormatCondition.Format> <dx:Format Icon="{dx:IconSet Name=Stars3_1}" /> </dxg:FormatCondition.Format> </dxg:FormatCondition> </ContentControl> </DataTemplate> <local:FormatConditionSelector x:Key="selector" BackgroundTemplate="{StaticResource BackgroundFormat}" FontTemplate="{StaticResource FontFormat}" IconTemplate="{StaticResource IconFormat}" /> </Grid.Resources> </Grid> </Window>
C#
public class FormatConditionSelector : DataTemplateSelector { public override DataTemplate SelectTemplate(object item, DependencyObject container) { if(!(item is FormattingRule)) return null; var vm = item as FormattingRule; switch(vm.Type) { case FormattingType.Icon: return IconTemplate; case FormattingType.Font: return FontTemplate; case FormattingType.Background: return BackgroundTemplate; default: return null; } } public DataTemplate BackgroundTemplate { get; set; } public DataTemplate FontTemplate { get; set; } public DataTemplate IconTemplate { get; set; } }
注意:如果可以使用單個模板描述所有條件格式,則無需創建模板選擇器。 而是,將此模板分配給網格視圖的TableView.FormatConditionGeneratorTemplate (TreeListView的TreeListView.FormatConditionGeneratorTemplate)屬性。
自定義GridControl
最後,指定網格視圖的FormatConditionGeneratorTemplateSelector和FormatConditionsSource屬性。TableView.FormatConditionsSource(TreeListView.FormatConditionsSource)屬性指定網格生成條件格式的來源,TableView.FormatConditionGeneratorTemplateSelector (TreeListView.FormatConditionGeneratorTemplateSelector) 屬性指定模板選擇器,該選擇器根據其類型爲每種條件格式返回一個模板。
XAML
<dxg:GridControl AutoGenerateColumns="AddNew" EnableSmartColumnsGeneration="True" ItemsSource="{Binding Orders}"> <dxg:GridControl.View> <dxg:TableView FormatConditionGeneratorTemplateSelector="{StaticResource selector}" FormatConditionsSource="{Binding Rules}" /> </dxg:GridControl.View> </dxg:GridControl>
下圖顯示了結果。
DevExpress技術交流羣3:700924826 歡迎一起進羣討論