2013-05-21 77 views
1

所有這些都是一個簡單的問題。我有使用使用MVVM限制WPF中綁定到DataGrid的屬性

<DataGrid ItemsSource="{Binding Path=Resources}" ...></DataGrid> 

與我已綁定到一個ViewModel一個DataGrid一個MVVM應用,其中Resources經由

public ObservableCollection<ResourceViewModel> Resources { get; private set; } 

但是限定在ResourceViewModel類,我不僅有我想性質出現在DataGrid,但其他屬性我想要出現在DataGrid。該ResourceViewmodel類是

public class ResourceViewModel : WorkspaceViewModel, IDataErrorInfo 
{ 
    readonly Resource resource; 
    readonly ResourceDataRepository resourceRepository; 
    private bool isSelected; 

    public ResourceViewModel(Resource resource, ResourceDataRepository resourceRepository) 
    { 
     if (resource == null) 
      throw new ArgumentNullException("resource"); 
     if (resourceRepository == null) 
      throw new ArgumentNullException("resourceRepository"); 
     this.resource = resource; 
     this.resourceRepository = resourceRepository; 
    } 

    public string KeyIndex 
    { 
     get { return this.resource.KeyIndex; } 
     set 
     { 
      if (value == this.resource.KeyIndex) 
       return; 
      this.resource.KeyIndex = value; 
      base.OnPropertyChanged("KeyIndex"); 
     } 
    } 

    public string FileName 
    { 
     get { return this.resource.FileName; } 
     set 
     { 
      if (value == this.resource.FileName) 
       return; 
      this.resource.FileName = value; 
      base.OnPropertyChanged("FileName"); 
     } 
    } 

    public List<string> ResourceStringList 
    { 
     get { return this.resource.ResourceStringList; } 
     set 
     { 
      if (Utilities.Utilities.ScrambledEquals<string>(this.resource.ResourceStringList, value)) 
       return; 
      this.resource.ResourceStringList = value; 
      base.OnPropertyChanged("ResourceStringList"); 
     } 
    } 

    public bool IsSelected 
    { 
     get { return isSelected; } 
     set 
     { 
      if (value == isSelected) 
       return; 
      isSelected = value; 
      base.OnPropertyChanged("IsSelected"); 
     } 
    } 
} 

在哪裏我不想IsSelected出現在DataGrid,我想在ResourceStringList每個項目出現在Datagrid的不同列。我的問題是:

1.如何防止IsSelectedDataGrid中顯示爲[Checkbox]?

2.如何獲取與DataGrid的綁定,以自動在單獨列中顯示項目?

你嘗試過什麼:

  1. 我試圖從ResourceViewmodel類繼承並綁定到這個代替,但是這是令人厭惡的,我想另一個更優雅的解決方案;請 :]。

  2. 我不知道如何繼續這一個。存儲在List中的項目數量是可變的,並且在運行時設置 - 因此這需要是List

一如既往,非常感謝您的時間。

+1

您可以手動創建自己的列的屬性。有關更多信息,請參閱[DataGrid.AutoGenerateColumns](http://msdn.microsoft.com/zh-cn/library/system.windows.controls.datagrid.autogeneratecolumns.aspx)。 – Silvermind

+0

如果ResourceStringList中的項目數量對於每一行不同,您想要生成多少列,並且它們的頭應該是什麼? – LPL

+0

當人們在MVVM模式中使用ObservableCollection時,我總是感到困惑。如果你使用MVVM,我認爲它不是必須的.​​.....我真的從不需要它,因爲總是沒有它的解決方案。 :/ –

回答

4

我認爲這些選項是關閉自動生成Silvermind提到(即設置DataGrid.AutoGenerateColumns爲false,然後定義列)或實現ITypedList。例如,您可以創建一個實現ITypedList的派生ObservableCollection,並根據您放入要隱藏的屬性的某些屬性返回屬性。

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     this.DataContext = new TypedListObservableCollection<Foo>(); 

     InitializeComponent(); 
    } 
} 

public class TypedListObservableCollection<T> : ObservableCollection<T> 
    , ITypedList 
{ 
    public TypedListObservableCollection() 
    { 
    } 

    PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) 
    { 
     return TypeDescriptor.GetProperties(typeof(T), new Attribute[] { BrowsableAttribute.Yes }); 
    } 

    string ITypedList.GetListName(PropertyDescriptor[] listAccessors) 
    { 
     return typeof(T).Name; 
    } 
} 

public class Foo 
{ 
    public string Name 
    { 
     get; 
     set; 
    } 

    [Browsable(false)] 
    public bool IsSelected 
    { 
     get; 
     set; 
    } 
} 
+0

+1感謝您的幫助。你可以提供一些建議,告訴我如何使用我的'List ResourceStringList'中的條目填充'DataGrid'列,因爲此時'DataGrid'只顯示'(Collection)'列。有人提到,從列表獲得的列會得到什麼標題:有沒有辦法提供這個?非常感謝您的時間... – MoonKnight

+0

@LPL指出,如果ResourceStringList至少在理論上每個數據項可以有不同數量的項目並且必須定義列所有的項目?如果您知道項目的最大數量,並且希望爲每個項目生成一列,那麼理論上可以創建一個派生的PropertyDescriptor,它表示每個列,並返回從GetItemProperties返回的PropertyDescriptorCollection中的那些列。 – AndrewS

+0

我不知道如果DataGrid響應列添加/刪除時,但如果是這樣,你需要它,那麼你需要編寫自己的自定義IBindingList實現,並在添加/刪除列時引發ListChanged。 – AndrewS

1

對我來說,它只是更容易不自動生成列。但是,這是個人喜好,所以我覺得不能讓某些屬性暴露的最簡單的方法是使用接口的電源:)

  1. 綁定到IResourceViewModel的的ObservableCollection - 使資源屬性界面的列表,而不是具體類型
  2. 化妝ResourceViewModel實施IResourceViewModel
  3. 在IResourceViewModel刪除你不希望到電網可見從接口
+0

雖然這會限制屬性,但它也意味着你不會自動添加新的功能(假設你想這樣做),因爲T不會是可創建的類型,所以你將不得不使用BindingList 並處理AddingNew或自己實現IEditableCollectionView或IBindingList。 – AndrewS

+0

是真實的(某一點 - 讓事情開箱即用),這就是爲什麼我在發佈我之前給你的答案+1的原因。然而,在視圖模型中使用Add命令並處理列表操作也可以實現 –