0

I have searched all over and keep finding similar examples that are not working for me. Can someone point out where I am messing up?

I have two tables AlarmName and AlarmLevel. Linked by a foreign key AlarmName.AlarmLevelID -> AlarmLevel.Id.

I have the following in my XAML:

                <DataGrid Name="Alarms"  AutoGenerateColumns="false">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="75" />
                    <DataGridTextColumn Binding="{Binding Description}" Header="Description" />
                    <DataGridTextColumn Binding="{Binding AlarmLevel.Name}" Header="AName" Width="75"/>

                    <DataGridTemplateColumn Header="Alarm Level">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox ItemsSource="{Binding DataContext.AlarmLevel, RelativeSource={RelativeSource  AncestorType={x:Type DataGrid}}}"
                                          DisplayMemberPath="Name"  
                                          SelectedValuePath="AlarmLevelID"
                                          SelectedValue="{Binding Id}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>

            </DataGrid>

And the following in my code behind:

UISimulation1.Data.UISimulationDBDataContext db = new UISimulation1.Data.UISimulationDBDataContext();

var alarm = (from v in db.AlarmNames
            select v);

Alarms.ItemsSource = alarm;

The DataGridTextColumns work and pull the right data. However, I can not make the combobox work or display anything no matter what I try.

Clearly, I am missing something obvious; but have tried 50 variants of the combobox based on google examples with zero results.

--rt

Robert
  • 3
  • 2

2 Answers2

0

You need to expose the records in the AlarmLevel table using a public property that you bind the ItemsSource property of the ComboBox to. Please refer to the following sample code.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        using (UISimulation1.Data.UISimulationDBDataContext db = new UISimulation1.Data.UISimulationDBDataContext())
        {
            AlarmNames = (from v in db.AlarmNames
                          select v).ToList();

            AlarmLevels = (from v in db.AlarmLevels
                           select v).ToList();
        }
    }

    public IEnumerable AlarmNames { get; private set; }

    public IEnumerable AlarmLevels { get; private set; }
}

<DataGrid Name="Alarms" ItemsSource="{Binding AlarmNames}" AutoGenerateColumns="false">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="75" />
        <DataGridTextColumn Binding="{Binding Description}" Header="Description" />
        <DataGridTextColumn Binding="{Binding AlarmLevel.Name}" Header="AName" Width="75"/>
        <DataGridTemplateColumn Header="Alarm Level">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding DataContext.AlarmLevels, RelativeSource={RelativeSource  AncestorType={x:Type DataGrid}}}"
                                          DisplayMemberPath="Name"  
                                          SelectedValuePath="AlarmLevelID"
                                          SelectedValue="{Binding Id}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>
mm8
  • 163,881
  • 10
  • 57
  • 88
  • I have done this in testing and with out using an item source you end up with a blank datagrid. this.datacontext = this Does not seem to work. As mentioned, setting the "itemSource" source will populate some of the datagrid; but the combobox can not get access to it (from my testing) – Robert Jan 09 '17 at 23:14
  • Did you really bind the ItemsSource property to the AlarmNames property?: – mm8 Jan 10 '17 at 08:08
  • Found the not displaying problem as that was merely a type-o on my part. It now works to a point; however nothing is selected by default. I switched SelectedValuePath to "AlarmNames.AlarmLevelID" and I get an error can not access a disposed object. This seems valid as I try to work backwards through the stack trace of the code behind I get the same error. It appears the combo box is not tracing up the relative source path to the parent grid. (as stated by the poster, it seems like it might not be feasible)? Really odd something realitively simple and common is so difficult in wpf. – Robert Jan 10 '17 at 16:14
  • SelectedValue="{Binding Id}" means that "Id" should be a property of the AlarmName entity and SelectedValuePath="AlarmLevelID" means that AlarmLevelID should be a property of the AlarmLevel entity. These properties should be of the same type. – mm8 Jan 10 '17 at 16:18
  • Thanks, that did it. Seems backwards, to me in how it works; but would not be the first time I felt that. – Robert Jan 10 '17 at 19:43
0

The DataGrid columns don’t belong to the visual or logical tree of the DataGrid, see this

Community
  • 1
  • 1
mechanic
  • 761
  • 6
  • 11