4

It would be best if showed you my code first and then ask the question:

<Window  DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<DataGrid ItemsSource="{Binding Printers}" >
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Drucker Typ" ItemsSource="{Binding Relative" SelectedItemBinding="{Binding PrinterType, Mode=TwoWay}"  Width="Auto" ItemsSource="{Binding}" />
</DataGrid.Columns>
</DataGrid>
</Window>

I have the DataGridComboBoxColumn and want to bind the ItemsSource to the DataContext of the Window and the SelectedItem to the current ItemsSource Object of the DataGrid.

How can this be done ?

Thanks!

TheBoyan
  • 6,802
  • 3
  • 45
  • 61
raphi011
  • 502
  • 1
  • 6
  • 23
  • Could explain what object-model you are trying the to bind to? You are trying to bind the column to the types of printers? – Bjorn Coltof Jul 26 '11 at 13:06

6 Answers6

4

To avoid the ElementName where you have to be well aware of the NameScope you can also use FindAncestor. Here you define the Type of the parent object you want to bind to.

Example:

<TextBlock Text=”{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Text}” />
fixagon
  • 5,506
  • 22
  • 26
  • Tried this: ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type main:DataBaseSettings}}, Path=PrinterTypes}" And got this System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='Etikett_Creator.DataBaseSettings', AncestorLevel='1''. BindingExpression:Path=PrinterTypes; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=48619823); target property is 'ItemsSource' (type 'IEnumerable') – raphi011 Jul 26 '11 at 13:03
  • tried this: ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=PrinterTypes}" got this: System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=PrinterTypes; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=3257321); target property is 'ItemsSource' (type 'IEnumerable') – raphi011 Jul 26 '11 at 13:04
  • 2
    try to use Path=DataContext.PrinterTypes – fixagon Jul 26 '11 at 13:05
  • You need to specify that you are binding to the DataContext of object Window, and then your property name – Rachel Jul 26 '11 at 13:08
  • System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=DataContext.PrinterTypes; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=31473901); target property is 'ItemsSource' (type 'IEnumerable') Doesn't work either, think i've tried that already – raphi011 Jul 26 '11 at 13:12
  • Yes i've tried it with the type Window and the Type DataBaseSettings which is the type of my window! (Inherited from Window) – raphi011 Jul 26 '11 at 13:14
2

Use an ElementName binding expression. This will allow you to reference the window by name from within the binding expression.

http://msdn.microsoft.com/en-us/library/system.windows.data.binding.elementname.aspx

The usage is explained well here.

http://www.wpfdude.com/articles/BindingToElement.aspx

Scott Munro
  • 13,369
  • 3
  • 74
  • 80
  • Doesn't work .. gave the window the name "wnd1" and then set the binding to: ItemsSource="{Binding ElementName=wnd1, Path=PrinterTypes}" the corresponding error message: System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=PrinterTypes; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=40408429); target property is 'ItemsSource' (type 'IEnumerable') – raphi011 Jul 26 '11 at 12:54
  • This is because the binding expression is within a DataGrid column - I missed that. The other answer better fits your scenario. – Scott Munro Jul 26 '11 at 13:09
0

I was only able to get this working binding to a resource of the window:

<DataGridComboboxColumn ItemsSource="{Binding Path=PrinterTypes, Source={StaticResource MyDataContext}}" ... />

I cannot get it working with RelativeSources, FindAncestors, etc.

Pablonete
  • 1,504
  • 1
  • 14
  • 11
0

The following worked for me. Just wanted to post it, because the answer I used was baked into the comments of fix_likes_codes's answer. The key is prefixing DataContext before the property name in the path.

<Button Command="{Binding Path=DataContext.SaveCommand, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}"
        CommandParameter="{Binding}">
wakurth
  • 1,644
  • 1
  • 23
  • 39
0
<local:DataBaseSettings>
    <Grid>
        <DataGrid ItemsSource="{Binding Printers}">
            <DataGrid.Columns>
                <DataGridComboBoxColumn Header="Drucker Typ" 
                    ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataBaseSettings}}, Path=PrinterTypes}"
                    SelectedItem="{Binding PrinterType, Mode=TwoWay}" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</local:DataBaseSettings>

Note that if each Printer.PrinterType does not directly reference an item that exists in your Window's DataContext, you need to overwrite the .Equals() method of your PrinterType class to make the two items equal.

Something like

public override bool Equals(object obj)
{
    if (obj == null) return false;

    if (this.GetType() != obj.GetType()) return false;


    PrinterType printerType= (PrinterType)obj;

    return (this.Id == printerType.Id);
}
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • Printertypes is just an ObservableCollection of strings! – raphi011 Jul 26 '11 at 13:46
  • @Raphi001 It's impossible for your Window's DataContext to be both a Collection of strings and a Class which contains a property called `Printers`. What properties exist on your Window's DataContext class? If it contains two properties, one a collection of `Printer` objects called `Printers`, and the other a collection of strings called `PrinterTypes`, you need to bind your ComboBox's ItemSource to `DataContext.PrinterTypes` (see my edit) – Rachel Jul 26 '11 at 13:58
  • the datacontext of the window is the window itself, and this window contains 2 dependency properties. Printers, a collection of custom types, and printertypes, a string collection. I've tried to bind to the datacontext several times but it just doesn't seem to work, the error message says " cannot find source " – raphi011 Jul 26 '11 at 14:09
  • System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=DataContext.PrinterTypes; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=20467445); target property is 'ItemsSource' (type 'IEnumerable') "Etikett Creator.vshost.exe" (Verwaltet (v4.0.30319)): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll" geladen – raphi011 Jul 26 '11 at 14:09
  • @raphi011 The `Window` object does not contain a property called `PrinterTypes`. If this is a custom window, you need to bind to the RelativeSource of whatever your custom type is, then the property path of `PrinterTypes`. See my edit. – Rachel Jul 26 '11 at 14:25
0

for now i've found no other way to do this than setting the itemssource at runtime like this:

private void SetComboBoxItemssource()
    {
        PrinterTypes = database.GetPrinterTypes();

        DataGridComboBoxColumn cmbColumn = null;

        foreach (DataGridColumn column in dtaPrinters.Columns)
        {
            if ((cmbColumn = column as DataGridComboBoxColumn) != null)
                break;
        }
        if (cmbColumn == null)
            return;

        cmbColumn.ItemsSource = PrinterTypes;
    }

it works though ..

raphi011
  • 502
  • 1
  • 6
  • 23