Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CRM 2011 Silverlight Application - Can't Add Items to Combobox Inside DataGridTemplateColumn cell

I'm declaring a datagrid template column in my xaml like so:

<sdk:DataGridTemplateColumn x:Name="MyColumn" Header="User">
                            <sdk:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox 
                                    x:Name="comboBox1" />
                            </DataTemplate>
                            </sdk:DataGridTemplateColumn.CellTemplate>
                        </sdk:DataGridTemplateColumn>

I then try to populate the combobox like so:

DataServiceQuery<SystemUser> query = (DataServiceQuery<SystemUser>)_context.SystemUserSet;
                query.BeginExecute(OnUserSearchComplete, query);

(runs after the InitializeComponent() line)

And then:

private void OnUserSearchComplete(IAsyncResult result)
{
    var query = result.AsyncState as DataServiceQuery<SystemUser>;
    IEnumerable<SystemUser> response = query.EndExecute(result);

    ComboBox comboBox1 = (DataGrid.Columns[4] as DataGridTemplateColumn).CellTemplate.LoadContent() as ComboBox;

    // Enumerate over the results of the query
    foreach (SystemUser record in response)
    {
        comboBox1.Items.Add(record.FullName);
    }
}

However when I run the application in CRM, the combobox isnt popualted with my system users. Can anyone explain what it is I'm doing wrong? I've tried a few different approaches now and I just can't seem to get it to work..

Thanks,

Jack

EDIT; Debugging:

  • Response returns 3 system user objects - which is correct.
  • comboBox1 does not equal null.

Here is how my grid is laid out (similar to SDK example): enter image description here

EDIT2; It appears for some reason that my code isn't breaking into the foreach loop, any ideas?

EDIT3; Ok, so using the information provided by Andrew in his answer below I have the followig code:

                    //Removed for brevity

                    <sdk:DataGridTemplateColumn x:Name="SalesmanColumn" Header="Salesman" Width="150">
                        <sdk:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox
                                    x:Name="comboBox1"
                                    ItemsSource="{Binding SystemUsers, ElementName=MyUserControl}"
                                />
                            </DataTemplate>
                        </sdk:DataGridTemplateColumn.CellTemplate>
                    </sdk:DataGridTemplateColumn>

                    //Removed for brevity

                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
        </Grid>

Unfortunately my binding doesn't seem to be working, the reason I say this is because I used a string builder and a text box to store and display the user names as they were retrieved from CRM and they were all retreived correctly, but they didn't appear in the combobox. Can anyone explain why my binding is incorrect?

like image 814
Jack Nutkins Avatar asked Nov 30 '25 12:11

Jack Nutkins


1 Answers

Have you tried binding ComboBox.ItemsSource in XAML rather than adding directly to ComboBox.Items in code-behind? Perhaps something like this?

<UserControl x:Name="MyUserControl">
    <UserControl.Resources>
        <CollectionViewSource
            x:Key="MyCollectionViewSource"
            Source="{Binding SystemUsers, ElementName=MyUserControl}"
            />
    </UserControl.Resources>

    <!-- ... Omitted for brevity ... -->

        <sdk:DataGridTemplateColumn x:Name="MyColumn" Header="User">
            <sdk:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox
                        x:Name="comboBox1"
                        ItemsSource="{Binding Source={StaticResource MyCollectionViewSource}}"
                        />
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellTemplate>
        </sdk:DataGridTemplateColumn>
</UserControl>

And then in code-behind:

public ObservableCollection<string> SystemUsers { get; private set; }

public UserControl()
{
    this.InitializeComponent();
    this.SystemUsers = new ObservableCollection<string>();
}

private void OnUserSearchComplete(IAsyncResult result)
{
    var query = result.AsyncState as DataServiceQuery<SystemUser>;
    IEnumerable<SystemUser> response = query.EndExecute(result);

    this.SystemUsers.Clear();
    foreach (SystemUser record in response)
    {
        this.SystemUsers.Add(record.FullName);
    }
}

I'm guessing that the data grid calls LoadContent() at run time when it's creating cells, and I'm guessing that when you call LoadContent() in your code, you're getting a reference to a new instance of a ComboBox that is not actually in the grid (nor is it in the visual tree at all). The above solution should circumvent the issue, by making each ComboBox pull in its data rather than giving your code-behind the responsibilities of locating each ComboBox and pushing in the data.

like image 181
Andrew Avatar answered Dec 03 '25 02:12

Andrew



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!