[ad_1]
mvvm に続くビューモデル メソッド内で WPF データグリッドの列数を動的に取得するにはどうすればよいですか?
私が試したこと:
本質的に datagrid.columns.count
int 変数に変換しますが、mvvm を使用します。
解決策 1
通常はアクセスできないデータ バインディングを介してプロパティにアクセスするには、 Columns.Count
のプロパティ DataGrid
コントロールの周りにラッパーを記述し、カスタム プロパティを追加できます。
C#
public class MyDataGrid : DataGrid, IDisposable { private const int DefaultColumnCountValue = 0; private static readonly Type ctrlType = typeof(MyDataGrid); private const string ctrlName = nameof(MyDataGrid); public static readonly DependencyProperty ColumnCountProperty = DependencyProperty.Register(nameof(ColumnCount), typeof(int), ctrlType, new PropertyMetadata(DefaultColumnCountValue, OnColumnCountChanged)); [Bindable(true)] [Description("Column Count"), Category(ctrlName)] public int ColumnCount { get => (int)GetValue(ColumnCountProperty); set => SetValue(ColumnCountProperty, value); } public override void OnApplyTemplate() { base.OnApplyTemplate(); // listen for changes this.Columns.CollectionChanged += Columns_CollectionChanged; } private void Columns_CollectionChanged( object? sender, NotifyCollectionChangedEventArgs e) => ColumnCount = this.Columns.Count; private static void OnColumnCountChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) { // can do something here when the property value is changed } public void Dispose() => this.Columns.CollectionChanged -= Columns_CollectionChanged; }
これで、プロパティにバインドできます。
XML
<local:MyDataGrid x:Name="MyDataGrid" ColumnCount="{Binding ColumnCount, Mode=OneWayToSource}" ItemsSource="{Binding Items}" />
完全なデモは次のとおりです。
1. MainWindow
Xaml
XML
<Window x:Class="WpfDataGridCountHelper.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:WpfDataGridCountHelper" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.DataContext> <local:MainViewModel /> </Window.DataContext> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <local:MyDataGrid x:Name="MyDataGrid" ColumnCount="{Binding ColumnCount, Mode=OneWayToSource}" ItemsSource="{Binding Items}" /> <Grid Grid.Row="1" Margin="10"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Border BorderBrush="DarkGray" BorderThickness="2" Padding="20 10"> <TextBlock Margin="0 10" HorizontalAlignment="Stretch"> <Run FontWeight="Bold" Text="Column Count: "/> <Run Text="{Binding ColumnCount}"/> </TextBlock> </Border> <Button Grid.Column="1" Margin="10 0 0 0" Padding="20 10" Content="ADD COLUMN" Click="ButtonBase_OnClick"/> </Grid> </Grid> </Window>
2. MainWindow
ボタン クリック イベントのコード ビハインド (デモ目的のみ):
C#
public partial class MainWindow : Window { public MainWindow() => InitializeComponent(); private void ButtonBase_OnClick(object sender, RoutedEventArgs e) => MyDataGrid.Columns.Add(new DataGridTextColumn()); }
3. MainViewModel
+ ObservableObject
(INotifyPropertyChanged
ハンドラークラス)
C#
public abstract class ObservableObject : INotifyPropertyChanged { public void Set<TValue>( ref TValue field, TValue newValue, [CallerMemberName] string propertyName = "") { if (!EqualityComparer<TValue>.Default.Equals(field, default) && field!.Equals(newValue)) return; field = newValue; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler? PropertyChanged; } public class MainViewModel : ObservableObject { private int columnCount = 0; public int ColumnCount { get => columnCount; set => Set(ref columnCount, value); } public ObservableCollection<PersonModel> Items { get; set; } = new() { new() { Name = "Freddie", Age = 21 }, new() { Name = "Milly", Age = 18 }, new() { Name = "Caddie", Age = 23 }, }; } public class PersonModel : ObservableObject { private string? name; private int? age; public string? Name { get => name; set => Set(ref name, value); } public int? Age { get => age; set => Set(ref age, value); } }
をクリックすると ADD COLUMN
ボタンは、空白の列を追加します MyDataGrid
コントロール、次にトリガーをバインドし、 TextBlock
フッターの更新で ColumnCount
、すべてを介してバインドされます DataContext
(MainViewModel
)。
楽しみ!
[ad_2]
コメント