■ GridControl 클래스의 인스턴트 피드백 UI 모드에서 메모리 데이터를 병렬 처리하는 방법을 보여준다.
▶ OrderDataListSource.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; namespace TestProject { /// <summary> /// 주문 데이터 리스트 소스 /// </summary> public class OrderDataListSource : IListSource { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 잠금자 /// </summary> private static object _locker = new object(); #endregion ////////////////////////////////////////////////////////////////////////////////////////// Instance //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 주문 데이터 리스트 /// </summary> private List<OrderData> orderDataList; /// <summary> /// 카운트 /// </summary> private int count = 0; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 리스트 컬렉션 포함 여부 - ContainsListCollection /// <summary> /// 리스트 컬렉션 포함 여부 /// </summary> public bool ContainsListCollection { get { return false; } } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - OrderDataListSource(count) /// <summary> /// 생성자 /// </summary> /// <param name="count">카운트</param> public OrderDataListSource(int count) { this.count = count; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 리스트 구하기 - GetList() /// <summary> /// 리스트 구하기 /// </summary> /// <returns>리스트</returns> public IList GetList() { if(this.orderDataList == null) { lock(_locker) { if(this.orderDataList == null) { GenerateOrderData(); } } } return this.orderDataList; } #endregion ////////////////////////////////////////////////////////////////////////////////////////// Private #region 주문 데이터 생성하기 - GenerateOrderData() /// <summary> /// 주문 데이터 생성하기 /// </summary> private void GenerateOrderData() { this.orderDataList = new List<OrderData>(this.count); Random random = new Random(); int customerCount = Data.CustomerList.Count; int productCount = Data.ProductList.Count; for(int i = 0; i < this.count; i++) { OrderData orderData = new OrderData(); orderData.OrderID = i + 1; orderData.CustomerName = Data.CustomerList[random.Next(customerCount)]; orderData.OrderDate = DateTime.Today.Subtract(TimeSpan.FromDays(random.Next(180))); KeyValuePair<string, decimal> productKeyValuePair = Data.ProductList[random.Next(productCount)]; orderData.ProductName = productKeyValuePair.Key; orderData.Price = productKeyValuePair.Value; orderData.Quantity = random.Next(200) + 1; this.orderDataList.Add(orderData); } } #endregion } } |
▶ ViewModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
using System.ComponentModel; namespace TestProject { /// <summary> /// 뷰 모델 /// </summary> public class ViewModel : INotifyPropertyChanged { //////////////////////////////////////////////////////////////////////////////////////////////////// Event ////////////////////////////////////////////////////////////////////////////////////////// Public #region 속성 변경시 - PropertyChanged /// <summary> /// 속성 변경시 /// </summary> public event PropertyChangedEventHandler PropertyChanged; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 주문 데이터 리스트 소스 /// </summary> private OrderDataListSource orderDataListSource; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 주문 데이터 리스트 소스 - OrderDataListSource /// <summary> /// 주문 데이터 리스트 소스 /// </summary> public OrderDataListSource OrderDataListSource { get { return this.orderDataListSource; } set { if(this.orderDataListSource == value) { return; } this.orderDataListSource = value; OnPropertyChanged("OrderDataListSource"); } } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - ViewModel() /// <summary> /// 생성자 /// </summary> public ViewModel() { OrderDataListSource = new OrderDataListSource(1000000); } #endregion ////////////////////////////////////////////////////////////////////////////////////////// Protected #region 속성 변경시 처리하기 - OnPropertyChanged(propertyName) /// <summary> /// 속성 변경시 처리하기 /// </summary> /// <param name="propertyName">속성명</param> protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion } } |
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" xmlns:local="clr-namespace:TestProject" Width="800" Height="600" Title="인스턴트 피드백 UI 모드에서 메모리 데이터 병렬 처리하기" FontFamily="나눔고딕코딩" FontSize="16"> <Window.DataContext> <local:ViewModel /> </Window.DataContext> <Grid> <dx:PLinqInstantFeedbackDataSource x:Name="pLinqInstantFeedbackDataSource" ListSource="{Binding Path=OrderDataListSource}" /> <dxg:GridControl x:Name="gridControl" ItemsSource="{Binding ElementName=pLinqInstantFeedbackDataSource, Path=Data}"> <dxg:GridControl.Columns> <dxg:GridColumn x:Name="idGridColumn" FieldName="OrderID" Header="ID" Width="60" MinWidth="60" AllowColumnFiltering="False" AllowGrouping="False" /> <dxg:GridColumn x:Name="customerNameGridColumn" FieldName="CustomerName" Width="200" /> <dxg:GridColumn x:Name="orderDateGridColumn" FieldName="OrderDate" Width="100" AllowColumnFiltering="False"> <dxg:GridColumn.EditSettings> <dxe:DateEditSettings DisplayFormat="d" /> </dxg:GridColumn.EditSettings> </dxg:GridColumn> <dxg:GridColumn x:Name="productNameGridColumn" FieldName="ProductName" Width="200" /> <dxg:GridColumn x:Name="priceGridColumn" FieldName="Price" Width="60" /> <dxg:GridColumn x:Name="quantityGridColumn" FieldName="Quantity" Width="60" /> </dxg:GridControl.Columns> <dxg:GridControl.View> <dxg:TableView AutoWidth="False" ShowTotalSummary="False" RowAnimationKind="Opacity" /> </dxg:GridControl.View> </dxg:GridControl> </Grid> <i:Interaction.Triggers> <i:EventTrigger EventName="Closed"> <i:InvokeCommandAction Command="{Binding ElementName=pLinqInstantFeedbackDataSource, Path=DisposeCommand}" /> </i:EventTrigger> </i:Interaction.Triggers> </Window> |
▶ MainWindow.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.Windows; namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainWindow() /// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); } #endregion } } |