ObservableCollection を にバインドし、MVVM アプリケーションを使用する WPF で true にDataGrid
設定しました。AutoGenerateColumns
stop
では、どうすればspecific column
DataGrid に表示されるのでしょうか?
ここで同じ質問を見ました。しかし、私はより多くのMVVMアプローチを探しています。
または、これを行うことができます...
Command
通常、添付プロパティを使用してイベントを-s にバインドし、ビューモデルに直接バインドして、これを回避できます。
namespace YourNamespace // wrap that into e.g. 'xmlns:local="clr-namespace:YourNamespace"'
public static class Attach
{
public static ICommand GetAutoGenerateColumnEvent(DataGrid grid) { return (ICommand)grid.GetValue(AutoGenerateColumnEventProperty); }
public static void SetAutoGenerateColumnEvent(DataGrid grid, ICommand value) { grid.SetValue(AutoGenerateColumnEventProperty, value); }
public static readonly DependencyProperty AutoGenerateColumnEventProperty =
DependencyProperty.RegisterAttached("AutoGenerateColumnEvent", typeof(ICommand), typeof(Attach), new UIPropertyMetadata(null, OnAutoGenerateColumnEventChanged));
static void OnAutoGenerateColumnEventChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
DataGrid grid = depObj as DataGrid;
if (grid == null || e.NewValue is ICommand == false)
return;
ICommand command = (ICommand)e.NewValue;
grid.AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>((s, args) => OnAutoGeneratingColumn(command, s, args));
// handle unsubscribe if needed
}
static void OnAutoGeneratingColumn(ICommand command, object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (command.CanExecute(e)) command.Execute(e);
}
}
そしてあなたのXAMLで...
<DataGrid
local:Attach.AutoGenerateColumnEvent="{Binding AutoGeneratingColumnCommand}" AutoGenerateColumns="True" />
そして、あなたのビューモデルでは...
RelayCommand _autoGeneratingColumnCommand;
public RelayCommand AutoGeneratingColumnCommand
{
get
{
return _autoGeneratingColumnCommand ?? (_autoGeneratingColumnCommand = new RelayCommand(param =>
{
var e = param as DataGridAutoGeneratingColumnEventArgs;
if (e != null)
{
switch (e.PropertyName)
{
case "ID":
e.Cancel = true;
break;
default:
break;
}
}
},
param => true));
}
}
...RelayCommand : ICommand
実装は Web で見つけることができます (広く使用されています)
できる限りMVVMっぽいです。これには何も問題はありません。MVVM プロジェクトで使用しましたが、非常にうまく機能します。
私は AutoGeneratedColumns を使用していませんが、「バインド可能な」列はトリックを添付しています。
<DataGrid Name="dataGrid"
local:DataGridColumnsBehavior.BindableColumns="{Binding ColumnCollection}"
AutoGenerateColumns="False"
...>
そして実際の動作:
public class DataGridColumnsBehavior
{
public static readonly DependencyProperty BindableColumnsProperty =
DependencyProperty.RegisterAttached("BindableColumns",
typeof(ObservableCollection<DataGridColumn>),
typeof(DataGridColumnsBehavior),
new UIPropertyMetadata(null, BindableColumnsPropertyChanged));
private static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
DataGrid dataGrid = source as DataGrid;
ObservableCollection<DataGridColumn> columns = e.NewValue as ObservableCollection<DataGridColumn>;
dataGrid.Columns.Clear();
if (columns == null)
{
return;
}
foreach (DataGridColumn column in columns)
{
dataGrid.Columns.Add(column);
}
columns.CollectionChanged += (sender, e2) =>
{
NotifyCollectionChangedEventArgs ne = e2 as NotifyCollectionChangedEventArgs;
if (ne.Action == NotifyCollectionChangedAction.Reset)
{
dataGrid.Columns.Clear();
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Add)
{
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Move)
{
dataGrid.Columns.Move(ne.OldStartingIndex, ne.NewStartingIndex);
}
else if (ne.Action == NotifyCollectionChangedAction.Remove)
{
foreach (DataGridColumn column in ne.OldItems)
{
dataGrid.Columns.Remove(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Replace)
{
dataGrid.Columns[ne.NewStartingIndex] = ne.NewItems[0] as DataGridColumn;
}
};
}
public static void SetBindableColumns(DependencyObject element, ObservableCollection<DataGridColumn> value)
{
element.SetValue(BindableColumnsProperty, value);
}
public static ObservableCollection<DataGridColumn> GetBindableColumns(DependencyObject element)
{
return (ObservableCollection<DataGridColumn>)element.GetValue(BindableColumnsProperty);
}
}
では、あなたにとって「MVVM」的なアプローチとは正確には何を構成するのでしょうか? XAML にすべてを含めることは、「MVVM」パターンの目的ではありません。
あなたができる別のトリックもあります。基本的には、DataGridColumn のテンプレート化と、条件に基づいて列を折りたたむ特定のトリガーの作成を中心に展開します。「準備ができている」ソリューションはありませんが、うまくいきます。