2016-05-23 43 views
3

我使用WPF組合框過濾項目,但我決定把它放在我的datagrid,而不是我可以讓它工作可能在他們我只能讓它工作時在數據網格之外。Datagrid組合框獲取relativsource到工作

我認爲這個問題是因爲

RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, or ElementName=win 

沒有在數據網格所以我得到它是如何工作的支援。

這是錯誤我得到

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=SelectedParam; DataItem=null; target element is 'ComboBox' (Name='Krydsmålbox'); target property is 'SelectedValue' (type 'Object')

<DataGrid x:Name="hjuldata" 
ItemsSource="{Binding Source={StaticResource cvsTasks}}" 
CanUserAddRows="False" BorderBrush="#FF303030" Foreground="#FF00FB0B" Background="#FF303030" AutoGenerateColumns="False" GridLinesVisibility="None" VerticalAlignment="Center" Height="644" Canvas.Left="20" Canvas.Top="257" Width="1250" > 
<DataGrid.Columns> 
<DataGridTextColumn Binding="{Binding Krydsmålet}"> 
<DataGridTextColumn.HeaderTemplate> 
    <DataTemplate> 
     <ContentPresenter Content="{Binding Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"/> 
    </DataTemplate> 
</DataGridTextColumn.HeaderTemplate> 
    <DataGridTextColumn.Header> 
     <ComboBox x:Name="Krydsmålbox" Foreground="#FFEAEAEA" Background="#FF303030" FontSize="12" 
        Style="{StaticResource ComboBoxTest2}" ItemTemplate="{StaticResource cmbTemplate2}" 
        ItemsSource="{Binding}" SelectedValuePath="Krydsmålene" 
        SelectedValue = "{Binding SelectedParam, RelativeSource={RelativeSource FindAncestor, 
        AncestorType={x:Type Window}},UpdateSourceTrigger=PropertyChanged}" BorderBrush="#FF303030" Height="40" DockPanel.Dock="Top" IsSynchronizedWithCurrentItem="True" SelectionChanged="Krydsmålbox_SelectionChanged" Canvas.Left="813" Canvas.Top="96" Width="146"/> 
</DataGridTextColumn.Header> 
</DataGridTextColumn> 

數據模板

<DataTemplate x:Key="cmbTemplate2"> 
    <WrapPanel Margin="0 5 0 5" Height="30"> 
     <Image Width="10" Height="20" Stretch="Fill" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,15,0"/> 
     <Label Content="{Binding Krydsmålene}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16" Foreground="#FF00FB0B"/> 
    </WrapPanel> 
</DataTemplate> 

CS

public event PropertyChangedEventHandler PropertyChanged; 

[NotifyPropertyChangedInvocator] 
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
{ 
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
} 

public string SelectedParam 
{ 
    get { return _selectedParam; } 
    set 
    { 
     _selectedParam = value; OnPropertyChanged("SelectedParam"); 
     if (_selectedParam == "Krydsmål") { BindData(); } else { hjuldata.ItemsSource = FilterKategori().Tables[0].DefaultView; ; } 
    } 
} 

public DataSet DTbindkryds() 
{ 
    Data = @"SELECT Krydsmålene FROM Data.Krydsmål"; 
    //SQL statement to fetch entries from Krydsmål 
    DataSet dsdata = new DataSet(); 

    //Open SQL Connection 
    using (conn = new SqlConnection(connStrings)) 
    { 
     conn.Open(); 

     //Initialize command object 
     using (conn = new SqlConnection(connStrings)) 
     using (cmd = new SqlCommand(Data, conn)) 
     { 
      SqlDataAdapter adapters = new SqlDataAdapter(cmd); 

      //Fill the result set 
      adapters.Fill(dsdata); 
      conn.Close(); 
     } 
    } 
    return dsdata; 
} 

private void bindkrydsmål() 
{ 
    Krydsmålbox.ItemsSource = DTbindkryds().Tables[0].DefaultView; 
} 
+0

爲什麼不爲網格定義數據模板並定義數據類型,以便可以將選定值直接綁定到某個屬性? – ViVi

+0

因爲我無法獲得datatemplate與標題屬性 –

+0

這是可能的。搜索使用我已經tryed WPF DataGrid標題模板 – ViVi

回答

0

我認爲你真正的問題是非常小的,頻繁的與WPF開發商。更改SelectedValue像下面結合:

SelectedValue = "{Binding DataContext.SelectedParam, RelativeSource={RelativeSource FindAncestor, 
         AncestorType={x:Type Window}},UpdateSourceTrigger=PropertyChanged}" 

由於你沒有給你如何分配DataContextwindow的代碼,這是一個可行的選擇來檢查。如果是相同的window類,則綁定應該在沒有DataContext.的情況下工作,但datagrid內部不支持RelativeSource綁定的假設是錯誤的。只要元素位於控件的VisualTree中,並且您的組合框位於窗口的可視樹中,則將工作於RelativeSource。對?

爲了節省驗證事實的時間,下面是演示(使用代碼重用的最大值並在DataGrid的標題中使用模板創建)。

XAML:

<DataGrid ItemsSource="{Binding Items}" CanUserAddRows="False" AutoGenerateColumns="False" VerticalAlignment="Stretch" > 
    <DataGrid.Columns> 
     <DataGridTextColumn Binding="{Binding DeviceState}">     
      <DataGridTextColumn.Header> 
       <ComboBox HorizontalAlignment="Stretch" Width="200" SelectedValuePath="DeviceState" 
           ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.Items}" 
           SelectedValue = "{Binding SelectedParam, RelativeSource={RelativeSource FindAncestor, 
           AncestorType={x:Type Window}}}" > 
        <ComboBox.ItemTemplate> 
         <DataTemplate> 
          <Label Content="{Binding DeviceState}" VerticalAlignment="Center" HorizontalAlignment="Stretch"/> 
         </DataTemplate> 
        </ComboBox.ItemTemplate> 
       </ComboBox>          
      </DataGridTextColumn.Header> 
     </DataGridTextColumn> 
     <DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="200"/> 
    </DataGrid.Columns> 
</DataGrid> 

代碼背後:

public MainWindow() 
    { 
     Items = new List<Device>(); 
     Items.Add(new Device() { Name = "Device1",DeviceState = 1 }); 
     Items.Add(new Device() { Name = "Device2", DeviceState = 2 }); 
     Items.Add(new Device() { Name = "Device3", DeviceState = 3 }); 
     Items.Add(new Device() { Name = "Device4", DeviceState = 4 }); 
     Items.Add(new Device() { Name = "Device5", DeviceState = 5 }); 
     InitializeComponent(); 

    } 

    public List<Device> Items { get; set; } 

    private string _selectedParam = "1"; 
    public string SelectedParam 
    { 
     get { return _selectedParam; } 
     set 
     { 
      _selectedParam = value; 
      UpdateProperty("SelectedParam");     
     } 
    } 

輸出:

Combobox in datagrid header

正如你可以在處於datagrid報頭中的combobox默認具有選定的項目,並正在使用relativesource結合,你可以看到在上面XAML反射輸出看到。

3

不要在Header財產使用一個DataTemplate,用它在HeaderTemplate像這樣:

<DataGridTextColumn.HeaderTemplate> 
    <DataTemplate> 
    <ComboBox x:Name="Krydsmålbox" Foreground="#FFEAEAEA" Background="#FF303030" FontSize="12" 
    Style="{StaticResource ComboBoxTest2}" ItemTemplate="{StaticResource cmbTemplate2}" 
    ItemsSource="{Binding}" SelectedValuePath="Krydsmålene" 
    SelectedValue = "{Binding SelectedParam, RelativeSource={RelativeSource FindAncestor, 
    AncestorType={x:Type Window}},UpdateSourceTrigger=PropertyChanged}" BorderBrush="#FF303030" Height="40" DockPanel.Dock="Top" IsSynchronizedWithCurrentItem="True" SelectionChanged="Krydsmålbox_SelectionChanged" Canvas.Left="813" Canvas.Top="96" Width="146"/> 
    </DataTemplate> 
</DataGridTextColumn.HeaderTemplate> 

一旦你這樣做,既ElementNameRelativeSource應該工作。

如果您希望能夠在後面的代碼中通過名稱來引用組合框,您可以使用ContentPresenter來呈現您想要的任何類型的標題(我認爲默認的HeaderTemplate是一個TextBlock而不是ContentPresenter):

<DataGridTextColumn.HeaderTemplate> 
    <DataTemplate> 
    <ContentPresenter Content="{Binding Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"/> 
    </DataTemplate> 
</DataGridTextColumn.HeaderTemplate> 
<DataGridTextColumn.Header> 
    <ComboBox x:Name="Krydsmålbox" Foreground="#FFEAEAEA" Background="#FF303030" FontSize="12" 
     Style="{StaticResource ComboBoxTest2}" ItemTemplate="{StaticResource cmbTemplate2}" 
     ItemsSource="{Binding}" SelectedValuePath="Krydsmålene" 
     SelectedValue = "{Binding SelectedParam, RelativeSource={RelativeSource FindAncestor, 
     AncestorType={x:Type Window}},UpdateSourceTrigger=PropertyChanged}" BorderBrush="#FF303030" Height="40" DockPanel.Dock="Top" IsSynchronizedWithCurrentItem="True" SelectionChanged="Krydsmålbox_SelectionChanged" Canvas.Left="813" Canvas.Top="96" Width="146"/> 
</DataGridTextColumn.Header> 
+0

它告訴我,krydsmålbox不存在於當前上下文中 –

+0

@ominidata你是否試圖在代碼後面使用組合框?如果是這樣,那麼是的,它將不再可用。 – FriendlyGuy

+0

@ominidata我已經添加了一個示例,允許您引用它後面的代碼(通過ContentPresenter) – FriendlyGuy