简体   繁体   中英

Binding ComboBox ItemsSource in DataGrid RowDetailsTemplate

I am trying to bind an ItemsSource to a ComboBox in a RowDetailsTemplate . If I place a ComboBox outside the grid it works fine. I think this is occureing because of the ItemsSource property on the grid may be throwing off the ComboBox within the RowDetailsTemplate. XAML is below any thoughts?

Categories and CatTypes are two different ObservableCollection s.

No error is occurring; the ComboBox just appears empty.

<ComboBox ItemsSource="{Binding CatTypes}"></ComboBox>
        <my:DataGrid Name="gridProds" AutoGenerateColumns="False"
        AlternatingRowBackground="Gainsboro" ItemsSource="{Binding Categories}">
            <my:DataGrid.Columns>
                <my:DataGridTextColumn x:Name="CatId" Header="CatID" Width="Auto" Binding="{Binding CategoryID}" />
                <my:DataGridTextColumn Header="CatName" Width="Auto" Binding="{Binding CategoryName}" />
            </my:DataGrid.Columns>
            <my:DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <Border>
                        <StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <Label>ID:</Label>
                                <TextBox Name="txtGridCatId" Text="{Binding CategoryID}"/>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <Label>Category Type:</Label>
                                <ComboBox ItemsSource="{Binding CatTypes}"></ComboBox>
                            </StackPanel>
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </my:DataGrid.RowDetailsTemplate>
        </my:DataGrid>

There is a class in the called DataSource in which the following is done:

private ObservableCollection<string> _cattypes = new ObservableCollection<string> { };

    public ObservableCollection<string> CatTypes
    {
        get
        {

            _cattypes = new ObservableCollection<string> { };

            SqlConnection con = new SqlConnection("MyConnStringHere;");
            SqlCommand cmd = new SqlCommand("Select ID, CatType from PfCategoryType ORDER BY CatType", con);
            con.Open();
            SqlDataReader rdr = cmd.ExecuteReader();

            while (rdr.Read())
            {
                string CatType = (string)rdr["CatType"];
                _cattypes.Add(CatType);

            }

            con.Close();

            return _cattypes;
        }
    }

In the MainWindow.xaml.cs I have:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataSource dataSource = new DataSource();
        this.DataContext = dataSource;
    }
}

If you checked the debug output in VS you would see the actual binding error. Most likely below code will fix it for you.

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=CatTypes}" />

If you can't get RelativeSource to work then use names. The property CatTypes is a property of some class which you created an object for and set as datacontext to some control. Just give that control a name (for example myControl) and bind like this:

<ComboBox ItemsSource="{Binding ElementName=myControl, Path=CatTypes}" />

If that don't work you need to post more of your code to figure out what you are doing wrong.

What happens if you try this?

<ComboBox DataContext="{Binding DataContext, ElementName=myControl}" ItemsSource="{Binding CatTypes}" />

(Of course you'd rename "myControl" to match the name of your window.)

Here, we're setting the data context of the combo box to be the same as the data context of the window. Since this is also the same data context of the first combo box in your XAML, I imagine the second combo box will start behaving like the first. (Although I worry that this will result in some unnecessary database connections, one per grid row.)

On second thought, if you need to set other properties in the context of the row, you won't want to set the data context of the entire ComboBox. In that case, I'd try something like this.

<ComboBox ItemsSource="{Binding ElementName=myControl, Path=DataContext.CatTypes}" SelectedItem="{Binding CategoryType}" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM