From af88b6e5a30550429417188fed0b4e67d14890e9 Mon Sep 17 00:00:00 2001 From: hj615 Date: Wed, 3 Sep 2025 17:23:49 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20DataGrid=20=ED=8E=98=EC=9D=B4=EC=A7=95?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SmartAquaViewer/Classes/Converter.cs | 9 ++ .../Classes/DataGridAutoBuilder.cs | 96 ------------- .../Helper/DataGridAutoPageSizeBehavior.cs | 62 +++++++++ SmartAquaViewer/Resources/Generic.xaml | 1 + SmartAquaViewer/View/EnegyView.xaml | 44 +++++- SmartAquaViewer/View/GreenHouseView.xaml | 44 +++++- SmartAquaViewer/View/MonitoringView.xaml | 131 +++++++++++++++--- SmartAquaViewer/ViewModel/EnergyViewModel.cs | 48 +++++-- .../ViewModel/GreenHouseGasViewModel.cs | 46 ++++-- .../ViewModel/MonitoringViewModel.cs | 44 +++--- .../ViewModel/PagingViewModelBase.cs | 97 +++++++++++++ 11 files changed, 452 insertions(+), 170 deletions(-) delete mode 100644 SmartAquaViewer/Classes/DataGridAutoBuilder.cs create mode 100644 SmartAquaViewer/Helper/DataGridAutoPageSizeBehavior.cs create mode 100644 SmartAquaViewer/ViewModel/PagingViewModelBase.cs diff --git a/SmartAquaViewer/Classes/Converter.cs b/SmartAquaViewer/Classes/Converter.cs index 2e504a0..4e62067 100644 --- a/SmartAquaViewer/Classes/Converter.cs +++ b/SmartAquaViewer/Classes/Converter.cs @@ -40,4 +40,13 @@ namespace SmartAquaViewer.Classes public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => !(value is bool b && b); } + + public class OneBasedConverter : IValueConverter + { + public object Convert(object value, Type t, object p, CultureInfo c) => + value is int i ? (i + 1).ToString() : "1"; + public object ConvertBack(object value, Type t, object p, CultureInfo c) => + int.TryParse(value?.ToString(), out var v) ? Math.Max(1, v) - 1 : 0; + } + } diff --git a/SmartAquaViewer/Classes/DataGridAutoBuilder.cs b/SmartAquaViewer/Classes/DataGridAutoBuilder.cs deleted file mode 100644 index f155d9c..0000000 --- a/SmartAquaViewer/Classes/DataGridAutoBuilder.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows; - -namespace SmartAquaViewer.Classes -{ - public static class DataGridAutoBuilder - { - public static void BuildColumnsFromType(DataGrid grid, IEnumerable items, - Dictionary headerMap = null, string dateFormat = "yyyy-MM-dd HH:mm:ss") - { - grid.Columns.Clear(); - var props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); - - foreach (var p in props) - { - DataGridColumn col = CreateColumnForProperty(p, headerMap, dateFormat); - if (col != null) grid.Columns.Add(col); - } - - grid.ItemsSource = items; - } - - private static DataGridColumn CreateColumnForProperty(PropertyInfo p, - Dictionary headerMap, string dateFormat) - { - string header = headerMap != null && headerMap.TryGetValue(p.Name, out var h) ? h : p.Name; - var type = Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType; - - // bool → CheckBox - if (type == typeof(bool)) - { - return new DataGridCheckBoxColumn - { - Header = header, - Binding = new Binding(p.Name) { Mode = BindingMode.TwoWay } - }; - } - - // enum → ComboBox(읽기/쓰기) - if (type.IsEnum) - { - return new DataGridComboBoxColumn - { - Header = header, - ItemsSource = Enum.GetValues(type), - SelectedItemBinding = new Binding(p.Name) { Mode = BindingMode.TwoWay } - }; - } - - // DateTime → 포맷 - if (type == typeof(DateTime)) - { - return new DataGridTextColumn - { - Header = header, - Binding = new Binding(p.Name) - { - Mode = BindingMode.TwoWay, - StringFormat = dateFormat - } - }; - } - - // 숫자 → 우측정렬 - if (type == typeof(int) || type == typeof(long) || - type == typeof(float) || type == typeof(double) || type == typeof(decimal)) - { - var col = new DataGridTextColumn - { - Header = header, - Binding = new Binding(p.Name) { Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged } - }; - col.ElementStyle = new Style(typeof(TextBlock)) - { - Setters = { new Setter(TextBlock.TextAlignmentProperty, TextAlignment.Right) } - }; - return col; - } - - // 기본(문자 등) - return new DataGridTextColumn - { - Header = header, - Binding = new Binding(p.Name) { Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged } - }; - } - } - -} diff --git a/SmartAquaViewer/Helper/DataGridAutoPageSizeBehavior.cs b/SmartAquaViewer/Helper/DataGridAutoPageSizeBehavior.cs new file mode 100644 index 0000000..21aaa0c --- /dev/null +++ b/SmartAquaViewer/Helper/DataGridAutoPageSizeBehavior.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using SmartAquaViewer.ViewModel; + +namespace SmartAquaViewer.Helper +{ + public static class DataGridAutoPageSizeBehavior + { + public static readonly DependencyProperty EnableProperty = + DependencyProperty.RegisterAttached( + "Enable", typeof(bool), typeof(DataGridAutoPageSizeBehavior), + new PropertyMetadata(false, OnEnableChanged)); + + public static void SetEnable(DependencyObject d, bool v) => d.SetValue(EnableProperty, v); + public static bool GetEnable(DependencyObject d) => (bool)d.GetValue(EnableProperty); + + // 🔹 여기! 어느 페이저를 갱신할지 바인딩으로 지정 + public static readonly DependencyProperty PagerProperty = + DependencyProperty.RegisterAttached( + "Pager", typeof(IPager), typeof(DataGridAutoPageSizeBehavior), + new PropertyMetadata(null)); + + public static void SetPager(DependencyObject d, IPager? v) => d.SetValue(PagerProperty, v); + public static IPager? GetPager(DependencyObject d) => (IPager?)d.GetValue(PagerProperty); + + private static void OnEnableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is DataGrid dg) + { + if ((bool)e.NewValue) dg.SizeChanged += DataGrid_SizeChanged; + else dg.SizeChanged -= DataGrid_SizeChanged; + } + } + + private static void DataGrid_SizeChanged(object sender, SizeChangedEventArgs e) + { + if (sender is not DataGrid dg) return; + + // 1) 우선 명시된 Pager를 사용 + var pager = GetPager(dg); + + // 2) 없으면 DataContext에서 찾아봄 (메인 페이저 케이스) + pager ??= dg.DataContext as IPager; + + if (pager == null || dg.RowHeight <= 0 || dg.ActualHeight <= 0) return; + + double header = dg.ColumnHeaderHeight > 0 ? dg.ColumnHeaderHeight : 45; + double available = Math.Max(0, dg.ActualHeight - header); + int rows = Math.Max(1, (int)(available / dg.RowHeight)); + + if (pager.PageSize != rows) + pager.PageSize = rows; // 페이저 쪽에서 RebuildPage() 호출됨 + } + } + +} diff --git a/SmartAquaViewer/Resources/Generic.xaml b/SmartAquaViewer/Resources/Generic.xaml index a782844..73a1efc 100644 --- a/SmartAquaViewer/Resources/Generic.xaml +++ b/SmartAquaViewer/Resources/Generic.xaml @@ -173,6 +173,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +