raphi011
raphi011

Reputation: 502

Binding to a Datacontext of an ancestor

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!

Upvotes: 4

Views: 8566

Answers (6)

wakurth
wakurth

Reputation: 1644

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}">

Upvotes: 0

Scott Munro
Scott Munro

Reputation: 13576

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

Upvotes: 2

Pablonete
Pablonete

Reputation: 1524

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.

Upvotes: 0

raphi011
raphi011

Reputation: 502

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 ..

Upvotes: 0

Rachel
Rachel

Reputation: 132548

<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);
}

Upvotes: 0

fixagon
fixagon

Reputation: 5566

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}” />

Upvotes: 4

Related Questions