5

ObservableCollection を にバインドし、MVVM アプリケーションを使用する WPF で true にDataGrid設定しました。AutoGenerateColumns

stopでは、どうすればspecific columnDataGrid に表示されるのでしょうか?

ここで同じ質問を見ました。しかし、私はより多くのMVVMアプローチを探しています。

4

3 に答える 3

2

または、これを行うことができます...

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 で見つけることができます (広く使用されています)

于 2013-04-05T12:08:45.437 に答える
1

できる限り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 のテンプレート化と、条件に基づいて列を折りたたむ特定のトリガーの作成を中心に展開します。「準備ができている」ソリューションはありませんが、うまくいきます。

于 2013-04-05T10:41:19.340 に答える