2011-04-03 80 views
0

我想從Datogrids的ColumnTemplate中的UserControl訪問對象。WPF DataGrid,在ColumnTemplate的綁定中訪問DataGrid外的元素

這不起作用。現在我讀了它是因爲Datacontext。

我發現這個例子,應該至極解決這個問題:http://blog.errorok.com/2010/09/09/212/

但事件:ColumnDataContextChanged永遠不會在我的項目叫!

這裏是我的XAML的一部分:

 <DataGridTemplateColumn Header="Database-Fieldtype" Width="Auto" IsReadOnly="False" SortMemberPath="DatabaseFieldType"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <TextBlock Text="{Binding DatabaseFieldType}" /> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
       <DataGridTemplateColumn.CellEditingTemplate> 
        <DataTemplate> 
         <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ConfigurationTool:EditProtocolDatasets}}, Path=grdDatasets.SelectedItem.Storage.DatabaseFieldTypes}" 
            SelectedItem="{Binding DatabaseFieldType}" 
            VerticalAlignment="Top" Width="179" Padding="0" Margin="0"> 
          <ComboBox.ItemTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Name}" /> 
           </DataTemplate> 
          </ComboBox.ItemTemplate> 
         </ComboBox> 

        </DataTemplate> 
       </DataGridTemplateColumn.CellEditingTemplate> 
      </DataGridTemplateColumn> 

組態:EditProtocolDatasets是我的用戶,grdDatasets是另一種的Datagrid,到至極的SelectedItem我想綁定!

回答

1

好吧,我會建議一個完全不同的方向比我的第一個。我的猜測是你的grdDatasets的ItemsSource綁定了某些東西。

對於那將作爲您的DataContext的控制項目,確保它具有以下特點,或至少相當的結構:

public class ListOfDataSets : DependencyObject 
{ 
    public IEnumerable<DataSetOption> Items 
    { 
    get 
    { 
     ...Whatever you normally use to get your DataSetOptions... 
    } 
    } 

    public DataSetOption SelectedItem 
    { 
    get { return (DataSetOption)GetValue(SelectedItemProperty); } 
    set { SetValue(SelectedItemProperty, value); } 
    } 

    public static readonly DependencyProperty SelectedItemProperty = 
    DependencyProperty.Register("SelectedItem", typeof(DataSetOption), typeof(ListOfDataSets), new PropertyMetadata(null)); 

} 

這裏的關鍵是,你有一個屬性是您選擇的列表,以及代表這些項目之一的另一個屬性。

然後,在你的XAML,您的控件可以有以下結構:

<UserControl> 
    <UserControl.Resources> 
    <ConfigurationTool:ListOfDatasets x:Key=DataSetOptions /> 
    </UserControl.Resources> 
    <StackPanel Name="LayoutRoot"> 
    <DataGrid Name="grdDatasets" 
     ItemsSource="{Binding Source={StaticResource DataSetOptions}, Path=Items}" 
     SelectedItem="{Binding Source={StaticResource DataSetOptions}, Path=SelectedItem}" 
     ... 
    </DataGrid> 
... 
    <DataGrid Name="OtherDataGrid" ItemsSource="{Binding OtherSource}"> 
     <DataGrid.Columns> 
    ... 
    <DataGridTemplateColumn Header="Database-Fieldtype" Width="Auto" IsReadOnly="False" SortMemberPath="DatabaseFieldType"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding DatabaseFieldType}" /> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
        <DataGridTemplateColumn.CellEditingTemplate> 
         <DataTemplate> 
          <ComboBox ItemsSource="{StaticResource DataSetOptions}, Path=SelectedItem.Storage.DatabaseFieldTypes}" SelectedItem="{Binding DatabaseFieldType, Mode=TwoWay}" 
             VerticalAlignment="Top" Width="179" Padding="0" Margin="0"> 
           <ComboBox.ItemTemplate> 
            <DataTemplate> 
             <TextBlock Text="{Binding Name}" /> 
            </DataTemplate> 
           </ComboBox.ItemTemplate> 
          </ComboBox> 
           </DataTemplate> 
        </DataGridTemplateColumn.CellEditingTemplate> 
       </DataGridTemplateColumn> 
     </Datagrid.Columns> 
    </DataGrid> 
    </StackPanel> 
</UserControl> 

其實我試過這種結構出來,數據綁定工作正常。但是,如果DataSetOptions發生了很大變化,那麼此解決方案可能無法正常工作,除非您使用MVVM,並且ViewModel擅長跟蹤哪些選項可用,並將其正確顯示給View。

希望這是有道理的。我在回答之前實際嘗試了這一個。

我對我的原始答案並不正確,並且在我嘗試使用之前高估了RelativeSource的功能。

---低於原始文本---

我想我可以幫助,但我需要一些更多的細節。現在,我只是想擺脫假設。

假設1:您正在使用具有已定義ItemsSource的DataGrid的WPF UserControl。 假設2:UserControl有另一個元素,您希望DataGrid中的列有權訪問。

如果這兩個假設是正確的,那麼在WPF中比在Silverlight中有更好的問題。

DataGrid中的每一行都將在DataContext中工作,該DataContext由該行的Item組成。但是,您可以使用RelativeSource訪問單元的(或任何)DataContext的外部。

所以,如果你想上去可視化樹到你控制的寬度,你可以使用:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MyUserControl}}, Path=Width} 

這將在Visual樹向上追溯,直到類型的對象「的MyUserControl」是發現,在這一點上它將抓住「寬度」屬性並綁定到它。

該路徑不一定只有一個項目深。您可以根據需要在視覺樹上運行。然而,隨着這變得越來越複雜,你的代碼將變得更加脆弱。

如果這是不正確的,請發佈您的XAML(或類似的東西)並說出來,我會啓動一個測試環境並編輯我的帖子。

+0

你說得對,用你的兩個假設! 但是爲什麼DataContexes的代碼不起作用? 我也嘗試過用RelativeSoure,但我的問題是,我不想搜索控件的類型,我想通過名稱查找控件! 我現在tryed這麼: 的ItemsSource = 「{綁定的RelativeSource = {的RelativeSource FindAncestor,AncestorType = {X:類型組態:EditProtocolDatasets}},路徑= grdDatasets.SelectedItem.Storage.DatabaseFieldTypes}」 但這並不工作,因爲grdDatasets是沒有財產(這是一個控制!) – 2011-04-03 15:47:52

+0

你可以編輯你的原始文章包含XAML? – 2011-04-03 15:59:47

+0

我會嘗試你的新解決方案,但我認爲它會工作! 但是,您是否有任何想法,爲什麼解決方案在http://blog.errorok.com/2010/09/09/212/不起作用? – 2011-04-03 17:40:23