Binding to a Datacontext of an ancestor

我是研究僧i 提交于 2019-12-12 12:41:13

问题


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!


回答1:


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



回答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




回答3:


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



回答4:


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




回答5:


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.




回答6:


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


来源:https://stackoverflow.com/questions/6829731/binding-to-a-datacontext-of-an-ancestor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!