2013-04-05 5 views
1

ObservableCollection을 DataGrid에 바인딩하고 MVVM 응용 프로그램이 포함 된 WPF에서 AutoGenerateColumns을 true로 설정했습니다.AutoGenerateColumns가 True로 설정된 경우 DataGrid에서 특정 열을 중지하는 방법은 무엇입니까?

그런 다음 stopspecific column을 DataGrid에 표시하려면 어떻게해야합니까?

나는 동일한 질문을 보았다 here. 하지만 MVVM 접근 방식이 더 필요합니다.

+0

가능한 중복 http://stackoverflow.com/questions/4000132/-ad-there-a-way-to-hide-column-in-a-datagrid-autogeneratecolumns? rq = 1 – Fendy

+0

예입니다. 나는 대답을 보았다. 하지만 여전히 나는 그 대답에 만족하지 못합니다. – Haritha

+0

그러면 "나는 이것을 읽었으며 더 많은 MVVM 접근법을 찾고 있습니다."와 같은 질문을 분명히해야합니다. – Fendy

답변

7

MVVM은 UI와 데이터를 의미합니다. 레이어는 완전히 분리되어 있으며,보기 레이어는 단순히 데이터 레이어를 시각적으로 반사합니다.

그래서 열을 제외한의 "MVVM 방법은"이 배제이 발생하는 위치에 따라 달라집니다 :

  • 데이터 층, 열을 제외 데이터 계층에서 해당 열을 제거하기로됩니다.

    이것은 일반적으로 사용자의 DataGrid.ItemsSource이 바인딩되어있는 컬렉션을 수정하여 표시되지 않아야하는 데이터가 더 이상 포함되지 않음을 의미합니다.

    또는 응용 프로그램의 용도에 따라 "응용 프로그램 논리"로 계산되는 것은 제외 할 열의 수를 string 또는 List<string>으로 유지하고 해당 문자열에 대한 바인딩 방법을 찾은 다음 해당보기를 수정하는 것을 의미 할 수 있습니다 당신의보기 층, 열을 제외보기에서 해당 열을 제거하도록되어있는 경우 그 열 (사용자 지정 종속성 속성, 컨버터의 Tag 특성 + AutoGeneratingColumn 이벤트의 재사용, 트리거 등)

  • 을 제외하려면 층.

    는 보통 그러나 당신은 또한 ColumnName이 값에 동일의 경우 DataGridAutoGeneratingColumn 이벤트를 사용하고, 열 생성을 취소보기 층에서 열을 제외 할 수 있습니다, 자신을 AutoGenerateColumns="False"을 설정하고 <DataGrid.Columns> 지정하여 수행됩니다 question you linked과 같이 제외하려고합니다.
    private void DataGrid_AutoGeneratingColumn(
        object sender, DataGridAutoGeneratingColumnEventArgs e) 
    { 
        if ((string)e.Column.Header == "ID") 
        { 
         e.Cancel = true; 
        } 
    } 
    

은 MVVM의 요점은 UI 및 데이터 레이어를 분리하는 것입니다 기억하십시오. MVVM에서 코드 숨김을 사용하는 데는 아무런 문제가 없습니다. 코드가 UI/특정 로직이 아닌 데이터/응용 프로그램 관련 로직 만 제공하면됩니다.

+0

코드 비하인드에 대해 독단적 인 것이 라기보다는 합리적인 것이지요. – Dai

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"틱 방법으로 constitues 무엇? XAML의 모든 것이 "MVVM"패턴과 관련이 없습니다.

할 수있는 또 다른 속임수가 있습니다. 기본적으로 DataGridColumn 템플릿을 중심으로 특정 조건에 따라 열을 축소하는 특정 트리거를 작성합니다. 나는 "준비된"해결책이 없지만 작동 할 것입니다.

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에서 ... RelayCommand : ICommand 구현 당신이에서 찾을 수

<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)); 
    } 
} 

... 웹 (널리 사용되는)

관련 문제