SeanKilleen
SeanKilleen

Reputation: 8977

How do I use XAML to bind a DatagridComboBoxColumn to a ViewModel property that isn't in the DataGrid's ItemsSource?

What I'm Attempting

The XAML

<DataGrid ItemsSource="{Binding FilesToAdd}" Height="100" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="100" AutoGenerateColumns="False" Visibility="{Binding FilesAreQueued, Converter={StaticResource BoolToVisConverter}}">
    <DataGrid.Resources>
        <app:BindingProxy x:Key="Proxy" Data="{Binding}"/>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Header="File Will be Uploaded As" Binding="{Binding FileDisplayText}"/>
        <DataGridTextColumn Header="Size" Binding="{Binding FileSizeInText}"/>
        <DataGridComboBoxColumn ItemsSource="{Binding AvailableDocumentTypes}" Header="Document Type" Visibility="{Binding Data.DocumentTypesAreRequired, Converter={StaticResource BoolToVisConverter}, Source={StaticResource Proxy} }">
        </DataGridComboBoxColumn>
    </DataGrid.Columns>
</DataGrid>

Update 1: XAML I'm Trying now + DataContext Clarification

Per Kevin's suggestion, I tried:

<DataGridComboBoxColumn ItemsSource="{Binding DataContext.AvailableDocumentTypes, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window }}}" Header="Document Type" Visibility="{Binding Data.DocumentTypesAreRequired, Converter={StaticResource BoolToVisConverter}, Source={StaticResource Proxy} }"/>

Also tried:

<DataGridComboBoxColumn ItemsSource="{Binding Path=DataContext.AvailableDocumentTypes, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window }}}" Header="Document Type" Visibility="{Binding Data.DocumentTypesAreRequired, Converter={StaticResource BoolToVisConverter}, Source={StaticResource Proxy} }"/>

But I receive the error that it can't be found.

FYI, My DataContext is set in the following way:

In the XAML:

<Window x:Class="VEUploader.WPF.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:app="clr-namespace:VEUploader.WPF" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
        Title="{Binding WindowTitle}" SizeToContent="WidthAndHeight"
        DataContext="{StaticResource UploaderViewModel}"
        AllowDrop="True"
   >

In the code (so I can do dependency injection):

public MainWindow()
{
    var uploaderViewModel = new UploaderViewModel(ObjectFactory.GetInstance<IVEDocumentService>(), ObjectFactory.GetInstance<IArgumentSettingsRetriever>(), ObjectFactory.GetInstance<IVEBudgetService>());
    Resources["UploaderViewModel"] = uploaderViewModel;


    InitializeComponent();
}

Upvotes: 4

Views: 3001

Answers (1)

Kevin DiTraglia
Kevin DiTraglia

Reputation: 26058

I don't have a compiler in front of me, but I believe the syntax would look something like this:

{Binding DataContext.MyProperty, RelativeSource={RelativeSource Mode=FindAncestor, 
                             AncestorType={x:Type MyParentControl}}}

EDIT: Actually doing some testing of my own, for some reason the DataGridComboBoxColumn somehow cannot find the item source, but if you template your own combo box column, it works just fine. Not sure why that is, but this may be an acceptable work around.

<Window x:Class="WPFTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid ItemsSource="{Binding FilesToAdd}" >
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Document Type">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox
                                ItemsSource=
                                "{Binding DataContext.AvailableDocumentTypes, 
                                RelativeSource={RelativeSource FindAncestor, 
                                AncestorType={x:Type Window }}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Upvotes: 5

Related Questions