2011-05-12 143 views
1

我需要將一些數據綁定到具有可變列數的DataGrid。我做了它的工作使用下面的代碼:WPF:如何使DataGrid綁定動態列可編輯?

int n = 0; 
foreach (string title in TitleList) 
{ 
    DataGridTextColumn col = new DataGridTextColumn(); 
    col.Header = title; 
    Binding binding = new Binding(string.Format("DataList[{0}]", n++)); 
    binding.Mode = BindingMode.TwoWay; 
    col.Binding = binding; 
    grid.Columns.Add(col); 
} 

其中DataList的聲明爲:

public ObservableCollection<double> DataList { get; set; } 

和TitleList聲明爲:

public ObservableCollection<string> TitleList { get; set; } 

的問題是,即使我指定雙向綁定,它真的是單向的。當我點擊一個單元格來嘗試編輯時,我得到了一個異常「'EditItem'不允許用於這個視圖」。我是否錯過了約束性表達中的某些東西?

P.S.我從Deborah "Populating a DataGrid with Dynamic Columns in a Silverlight Application using MVVM"找到一篇文章。但是,我很難使其適用於我的情況(具體而言,我無法使標題綁定起作用)。即使它工作,我仍然面臨不一致的單元格樣式的問題。這就是爲什麼我想知道是否可以使我的上面的代碼工作 - 只需稍作調整?

編輯:我發現了另一篇文章,可能與我的問題有關:Implicit Two Way binding。看起來,如果你綁定到字符串列表使用

<TextBox Text="{Binding}"/> 

你會得到這樣的錯誤一個TextBox「雙向綁定需要路徑或XPath」。但問題可以很容易地通過使用

<TextBox Text="{Binding Path=DataContext, RelativeSource={RelativeSource Self}}"/> 

<TextBox Text="{Binding .}"/> 

任何人都可以給我一個提示,如果我的問題可以用類似的方式來解決能解決嗎?

+0

我編輯我的答案問題是你的收藏類型的雙。 – blindmeis

回答

2

你綁定到一個索引器?你能告訴我們你的DataList屬性是怎麼樣的嗎?

我前段時間做了一個索引屬性。

public SomeObjectWithIndexer DataList 
{get; set;} 


public class SomeObjectWithIndexer 
{ 
     public string this 
     { 
      get { ... } 
      set { ... }//<-- you need this one for TwoWay 
     } 
} 

編輯:你不能編輯你的財產的原因是你試圖編輯一個「雙字段」。 解決方法之一是將您的double包裝到INotifyPropertyChanged類中。

public class DataListItem 
{ 
    public double MyValue { get; set;}//with OnPropertyChanged() and stuff 
} 

那麼你可以使用一個

ObservableCollection<DataListItem> 

,你可以編輯你的價值。閹指數的問題都是一樣的住宿仍然存在:)

Binding binding = new Binding(string.Format("DataList[{0}].MyValue", n++)); 

EDIT2:工作示例:只是爲了顯示雙向工作

public class DataItem 
{ 
    public string Name { get; set; } 
    public ObservableCollection<DataListItem> DataList { get; set; } 

    public DataItem() 
    { 
     this.DataList = new ObservableCollection<DataListItem>(); 
    } 
} 

包裝雙:

public class DataListItem 
{ 
    private double myValue; 
    public double MyValue 
    { 
     get { return myValue; } 
     set { myValue = value; }//<-- set breakpoint here to see that edit is working 
    } 
} 

用戶控制數據網格

<UserControl x:Class="WpfStackoverflow.IndexCollectionDataGrid" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300"> 
<DataGrid ItemsSource="{Binding MyList}" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" /> 
     <DataGridTextColumn Header="Index1" Binding="{Binding Path=DataList[0].MyValue, Mode=TwoWay}" /> 
     <DataGridTextColumn Header="Index2" Binding="{Binding Path=DataList[1].MyValue, Mode=TwoWay}" /> 
    </DataGrid.Columns> 
</DataGrid> 
</UserControl> 

.cs

public partial class IndexCollectionDataGrid : UserControl 
{ 
    public IndexCollectionDataGrid() 
    { 
     InitializeComponent(); 
     this.MyList = new ObservableCollection<DataItem>(); 

     var m1 = new DataItem() {Name = "test1"}; 
     m1.DataList.Add(new DataListItem() { MyValue = 10 }); 
     m1.DataList.Add(new DataListItem() { MyValue = 20 }); 

     var m2 = new DataItem() { Name = "test2" }; 
     m2.DataList.Add(new DataListItem() { MyValue = 100 }); 
     m2.DataList.Add(new DataListItem() { MyValue = 200 }); 

     this.MyList.Add(m1); 
     this.MyList.Add(m2); 

     this.DataContext = this; 
    } 

    public ObservableCollection<DataItem> MyList { get; set; } 
} 

我希望你能在這個例子中找到正確的方向。

+0

@blindmeis:謝謝你的回答。我的DataList被聲明爲ObservableCollection 。 – newman

+0

hmm ObservableCollection的索引總是一樣的嗎? – blindmeis

+0

@blindmeis:我試圖通過將double轉換爲實現了INotifyChanged的對象並得到相同的錯誤。所以,我不確定它是否是索引器問題。 – newman