WPF使用DataGridComboBoxColumn完成綁定


  在使用DataGrid的時候,有時候需要使某些列為ComboBox,這時自然想到使用DataGridComboBoxColumn,但是如果使用的是ItemsSource數據綁定后台的對象,就會發現,這根本就不能用。

  首先,看有問題的代碼:

后台代碼
 1 using System.Windows;
 2 using System.Collections.ObjectModel;
 3 using System.ComponentModel;
 4 
 5 namespace WPFTest
 6 {
 7     /// <summary>
 8     /// 數據項
 9     /// </summary>
10     public class DataItem
11     {
12         public int Value { get; set; }
13         public DataItem(int val) { Value = val; }
14     }
15     /// <summary>
16     /// MainWindow.xaml 的交互邏輯
17     /// </summary>
18     public partial class MainWindow : Window
19     {
20         public MainWindow()
21         {
22             InitializeComponent();
23             // 選中數據
24             SelectedList.Add(new DataItem(1)); SelectedList.Add(new DataItem(2));
25             // 可選數據
26             SelectionList.Add(1); SelectionList.Add(2); SelectionList.Add(3);
27         }
28 
29         /// <summary>
30         /// 選中的數據列表
31         /// </summary>
32         public ObservableCollection<DataItem> SelectedList
33         {
34             get { return _selectedList; }
35             set { _selectedList = value; }
36         }
37         private ObservableCollection<DataItem> _selectedList = new ObservableCollection<DataItem>();
38 
39         /// <summary>
40         /// 可供選擇的數據列表
41         /// </summary>        
42         public ObservableCollection<int> SelectionList
43         {
44             get { return _selectionList; }
45             set { _selectionList = value; }
46         }
47         private ObservableCollection<int> _selectionList = new ObservableCollection<int>();
48 
49         // 顯示選中的
50         private void Button_Click(object sender, RoutedEventArgs e)
51         {
52             TBX_Selected.Text = "";
53             foreach (var item in SelectedList)
54                 TBX_Selected.Text += item.Value.ToString(" --->0<--- ");
55         }
56 
57     }
58 }

   前台為:

 1 <Window x:Class="WPFTest.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="WPFTest" Name="this" Height="350" Width="525">
 5     <StackPanel>
 6         <DataGrid ItemsSource="{Binding Path=SelectedList,ElementName=this}" AutoGenerateColumns="False">
 7             <DataGrid.Columns>                
 8                 <DataGridTextColumn Header="文本模式" Binding="{Binding Path=Value}" />                
 9                 <DataGridComboBoxColumn Header="ComboBox模式"
10                                         SelectedValueBinding="{Binding Path=Value}"
11                                         ItemsSource="{Binding Path=SelectionList,ElementName=this}" />                
12             </DataGrid.Columns>
13         </DataGrid>
14         <Button Content="觀察選中的數據" Click="Button_Click" Margin="10"/>
15         <TextBox Name="TBX_Selected" />
16     </StackPanel>
17 </Window>

  在這里通過把Window控件的Name設置為this,然后在綁定的時候指定ElementName=this及Path屬性來關聯到后台數據源。為了測試是否有效,我還定義了一個TextBox來顯示SelectedList中的數據的值。首先,可以肯定的是,用DataGridTextColumn一點問題也沒有,數據可以正常地顯示和更新,但是使用DataGridComboBoxColumn時問題就出現了,數據不能顯示,就像什么都沒有綁定上去一樣:

  我在網上找了下資料,都與MSDN上的例子相似,DataGridComboBoxColumn對數據源有下面的要求:

 使用下列選項之一,若要填充下拉列表,首先設置 ComboBox 的 ItemsSource 屬性:

  於是,試試DataGridTemplateColumn來做ComboBox:  

1 <DataGridTemplateColumn Header="Template模式">
2     <DataGridTemplateColumn.CellTemplate>
3         <DataTemplate>
4             <ComboBox SelectedValue="{Binding Path=Value}" ItemsSource="{Binding Path=SelectionList,ElementName=this}" />    
5         </DataTemplate>
6     </DataGridTemplateColumn.CellTemplate>
7 </DataGridTemplateColumn>

  運行發現,顯示是正常了,但是不論我怎么改,SelectedList中的數據都不帶改變,我嘗試設置了ComboBox的各項屬性,也沒有成功。但是非常奇怪的地方是,如果在選擇后,去點了上面的DataGridComboBoxColumn ,數據就能正常正同步過去:

  我想這可能是DataGridComboBoxColumn在選擇后會觸發一個事件,完成同步工作。

  好了,這樣還是不行,我去了stackoverflow上找資料,問題終於得到了解決。基本上原因是這樣的:DataGrid的列並沒有數據上下文,所以DataGridTemplateColumn中的ComoBox從未添加到“Visual Tree(可視化樹)”中。只要Grid繪制了單元,並且得到了數據上下文后,就能正常地使用ItemsSource屬性來完成綁定了。修正后的代碼:

1 <DataGridComboBoxColumn Header="ComboBox模式(修正)">
2     <DataGridComboBoxColumn.EditingElementStyle>
3         <Style TargetType="ComboBox">
4             <Setter Property="ItemsSource" Value="{Binding Path=SelectionList,ElementName=this}" />
5             <Setter Property="SelectedValue" Value="{Binding Path=Value}" />
6         </Style>
7     </DataGridComboBoxColumn.EditingElementStyle>
8 </DataGridComboBoxColumn>

  這樣,數據能夠正常地同步了,但是如果不點中對應單元格,ComboBox就不會顯示出來,只有點中了才顯示,繼續參考資料,問題原因是上面只設置了EditingElementStyle(編輯時樣式),所以在選中編輯時就會出現ComboBox,要想一直顯示,還得設置ElementStyle,使它和EditingElementStyle一樣就行了:

<DataGridComboBoxColumn.ElementStyle>
    <Style TargetType="ComboBox">
        <Setter Property="ItemsSource" Value="{Binding Path=SelectionList,ElementName=this}" />
        <Setter Property="SelectedValue" Value="{Binding Path=Value}" />
    </Style>
</DataGridComboBoxColumn.ElementStyle>

  

  問題圓滿解決,其實也不難,只是不知道,沒想到而已,大家可以看看。

      好多人在評論里要DEMO,我沒有時間去一個一個發,直接就把前面例子的DEMO放這了,大家自行下載吧!

  轉載請注明原址:http://www.cnblogs.com/lekko/archive/2012/11/23/2784789.html 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM