0
votes

This may sound trivial but i have a problem with setting selected item in ComboBox ;)

What i want to achive:

I want to have the first element of the list selected after the page loads.

XAML Code:

               <DataTemplate>
                                    <ComboBox x:Name="DeviceComboBox" SelectedIndex="1" SelectionChanged="DeviceComboBox_SelectionChanged">
                                        <ComboBox.Items>
                                            <ComboBoxItem x:Name="Switch" Content="Switche"/>
                                            <ComboBoxItem x:Name="Firewall" Content="Firewalle"/>
                                            <ComboBoxItem x:Name="Host" Content="Hosty" />
                                            <ComboBoxItem x:Name="SRF1" Content="SRF1"/>
                                        </ComboBox.Items>
                                    </ComboBox>
                                </DataTemplate>

RESULT: AG_E_UKNOWN_ERROR [Line:49 Position:55] Line 49:

</ComboBox>

Error Details

    w MS.Internal.XcpImports.MethodEx(IntPtr ptr, String name, CValue[] cvData)
    w MS.Internal.XcpImports.MethodEx(DependencyObject obj, String name)
    w MS.Internal.XcpImports.DataTemplate_LoadContent(DataTemplate template)
    w System.Windows.Controls.DataGridTemplateColumn.GenerateElement(DataGridCell cell, Object dataItem)
    w System.Windows.Controls.DataGrid.PopulateCellContent(Boolean isCellEdited, DataGridColumn dataGridColumn, DataGridRow dataGridRow, DataGridCell dataGridCell)
    w System.Windows.Controls.DataGrid.AddNewCellPrivate(DataGridRow row, DataGridColumn column)
    w System.Windows.Controls.DataGrid.CompleteCellsCollection(DataGridRow dataGridRow)
    w System.Windows.Controls.DataGrid.GenerateRow(Int32 rowIndex, Int32 slot, Object dataContext)
    w System.Windows.Controls.DataGrid.InsertElementAt(Int32 slot, Int32 rowIndex, Object item, DataGridRowGroupInfo groupInfo, Boolean isCollapsed)
    w System.Windows.Controls.DataGrid.InsertRowAt(Int32 rowIndex)
    w System.Windows.Controls.DataGridDataConnection.NotifyingDataSource_CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
    w System.Windows.Data.PagedCollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
    w System.Windows.Data.PagedCollectionView.ProcessAddEvent(Object addedItem, Int32 addIndex)
    w System.Windows.Data.PagedCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) 
    w System.Windows.Data.PagedCollectionView.<.ctor>b__0(Object sender, NotifyCollectionChangedEventArgs args)
    w System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    w System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item)
    w System.Collections.ObjectModel.Collection`1.Add(T item)
    w LANOS.Views.Customers.onCustomerListLoaded(LoadOperation`1 loadOper)
    w System.ServiceModel.DomainServices.Client.DomainContext.<>c__DisplayClass13`1.<Load>b__11(LoadOperation lo)
    w System.ServiceModel.DomainServices.Client.LoadOperation.<>c__DisplayClass4`1.<Create>b__0(LoadOperation`1 arg)
    w System.ServiceModel.DomainServices.Client.LoadOperation`1.InvokeCompleteAction()
    w System.ServiceModel.DomainServices.Client.OperationBase.Complete(Object result)
    w System.ServiceModel.DomainServices.Client.LoadOperation.Complete(DomainClientResult result)
    w System.ServiceModel.DomainServices.Client.DomainContext.CompleteLoad(IAsyncResult asyncResult)
    w System.ServiceModel.DomainServices.Client.DomainContext.<>c__DisplayClass1b.<Load>b__17(Object )

Caused by: AG_E_UNKNOWN_ERROR [Line: 49 Position: 55]

    w MS.Internal.XcpImports.MethodEx(IntPtr ptr, String name, CValue[] cvData)
    w MS.Internal.XcpImports.MethodEx(DependencyObject obj, String name)
    w MS.Internal.XcpImports.DataTemplate_LoadContent(DataTemplate template)
    w System.Windows.Controls.DataGridTemplateColumn.GenerateElement(DataGridCell cell, Object dataItem)
    w System.Windows.Controls.DataGrid.PopulateCellContent(Boolean isCellEdited, DataGridColumn dataGridColumn, DataGridRow dataGridRow, DataGridCell dataGridCell)
    w System.Windows.Controls.DataGrid.AddNewCellPrivate(DataGridRow row, DataGridColumn column)
    w System.Windows.Controls.DataGrid.CompleteCellsCollection(DataGridRow dataGridRow)
    w System.Windows.Controls.DataGrid.GenerateRow(Int32 rowIndex, Int32 slot, Object dataContext)
    w System.Windows.Controls.DataGrid.InsertElementAt(Int32 slot, Int32 rowIndex, Object item, DataGridRowGroupInfo groupInfo, Boolean isCollapsed)
    w System.Windows.Controls.DataGrid.InsertRowAt(Int32 rowIndex)
    w System.Windows.Controls.DataGridDataConnection.NotifyingDataSource_CollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
    w System.Windows.Data.PagedCollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args)
    w System.Windows.Data.PagedCollectionView.ProcessAddEvent(Object addedItem, Int32 addIndex)
    w System.Windows.Data.PagedCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args)
    w System.Windows.Data.PagedCollectionView.<.ctor>b__0(Object sender, NotifyCollectionChangedEventArgs args)
    w System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    w System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item)
    w System.Collections.ObjectModel.Collection`1.Add(T item)
    w LANOS.Views.Customers.onCustomerListLoaded(LoadOperation`1 loadOper)
    w System.ServiceModel.DomainServices.Client.DomainContext.<>c__DisplayClass13`1.<Load>b__11(LoadOperation lo)
    w System.ServiceModel.DomainServices.Client.LoadOperation.<>c__DisplayClass4`1.<Create>b__0(LoadOperation`1 arg)
    w System.ServiceModel.DomainServices.Client.LoadOperation`1.InvokeCompleteAction()
    w System.ServiceModel.DomainServices.Client.OperationBase.Complete(Object result)
    w System.ServiceModel.DomainServices.Client.LoadOperation.Complete(DomainClientResult result)
    w System.ServiceModel.DomainServices.Client.DomainContext.CompleteLoad(IAsyncResult asyncResult)
    w System.ServiceModel.DomainServices.Client.DomainContext.<>c__DisplayClass1b.<Load>b__17(Object )

Any ideas?

2
Could the problem be that the selected index is set before the items are added? You could try to set the index after the window or control is loaded. Apart from that: What are doing in the SelectionChanged method?MatthiasG
Seleciton change makes a simple redirect to another web page. Nothing fancy, works fine without SelectedIndex property. Hmm how i can access DataTemplate object properties from Page's code behind? Seems like this.DeviceComboBox does not work.mike
If you want to create a ComboBox with a special behavior I would suggest to create a new class which derives from ComboBox and implements your behavior. That should do the job and you don't need a data template. Another way would be to create a Behavior element.MatthiasG

2 Answers

1
votes

As I read in your comments you want to use a ComboBox which automatically has a selection when it is loaded. Therefore I would suggest two possibilities: Writing a control deriving from ComboBox or adding a behavior to a default ComboBox.

Deriving from ComboBox:

public class MyComboBox : ComboBox
{
  public MyComboBox()
  {
    Loaded += ComboBoxLoaded;
  }

  private void ComboBoxLoaded(object sender, RoutedEventArgs e)
  {
    if(Count > 1)
    {
      SelectedIndex = 1;
    }
  }
}

Usage:

<MyComboBox>
  <ComboBoxItem x:Name="Switch" Content="Switche"/>
  <ComboBoxItem x:Name="Firewall" Content="Firewalle"/>
  <ComboBoxItem x:Name="Host" Content="Hosty" />
  <ComboBoxItem x:Name="SRF1" Content="SRF1"/>
</MyComboBox>

Implementing behavior:

A behavior class allows you to add a behavior to a control using xaml. The behavior is coded.

public class ComboBoxSelectionBehavior:Behavior<ComboBox>
{
  protected override void OnAttached()
  {
    base.OnAttached();
    AssociatedObject.Loaded += ComboBoxLoaded;
  }

  protected override void OnDetaching()
  {
    AssociatedObject.Loaded -= ComboBoxLoaded;
    base.OnDetaching();
  }

  private void ComboBoxLoaded(object sender, RoutedEventArgs e)
  {
    if(Count > 1)
    {
      SelectedIndex = 1;
    }
  }
}

Usage:

<ComboBox>
  <Interactivity:Interaction.Behaviors>
    <Behaviors:ComboBoxSelectionBehavior/>
  </Interactivity:Interaction.Behaviors>
  <ComboBoxItem x:Name="Switch" Content="Switche"/>
  <ComboBoxItem x:Name="Firewall" Content="Firewalle"/>
  <ComboBoxItem x:Name="Host" Content="Hosty" />
  <ComboBoxItem x:Name="SRF1" Content="SRF1"/>
</ComboBox>

Note, that for the usage of behaviors you need the Blend SDK to be installed.

0
votes

I suspect that you're getting an error because of the SelectionChanged event handler within the DataTemplate. I'm guessubg that the DataGrid you're using this template in can't find the event handler. Why do you need this event handler?

I get a similar error message with the following XAML:

MainPage.xaml:

<UserControl x:Class="Example.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <ResourceDictionary Source="Dictionary1.xaml" />
    </UserControl.Resources>
    <ItemsControl ItemsSource="ABC" ItemTemplate="{StaticResource failTemplate}" />
</UserControl>

Dictionary1.xaml:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DataTemplate x:Name="failTemplate">
        <ComboBox SelectionChanged="ComboBox_SelectionChanged">
            <ComboBoxItem Content="AAA" />
            <ComboBoxItem Content="BBB" />
            <ComboBoxItem Content="CCC" />
        </ComboBox>
    </DataTemplate>
</ResourceDictionary>