title: ComboBox default text show typeName of items type, instead of my own text property
body: <p>I have template for my <code>ComboBox</code>. taken from <a href="http://blogs.microsoft.co.il/blogs/justguy/archive/2009/01/19/wpf-combobox-with-checkboxes-as-items-it-will-even-update-on-the-fly.aspx" rel="nofollow">here</a>. Lets say each item is <code>Node</code> type.</p>
  
  <p>Its all work perfect, but one thing crash my mind. When I click between <code>ComboBoxItem</code> (this area i think one-pixel line), Text of ComboBox changed to TypeName of items (with namespace).</p>
  
  <p>I have overrided <strong>ToString()</strong> method of <code>Node</code> class, but <strong>CallStack</strong> shows, that program comes to it from <code>[External code]</code>.</p>
  
  <p>What should I do to <code>ComboBox.Text</code> show my string property instead of TypeName of <code>ComboBoxItem</code>?</p>
  
  <p>If I miss some detail, just point out what is.</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>Code is from hyperlink <strong>here</strong> above, with some changes.</p>
  
  <p>Usage:</p>
  
  <pre><code>&lt;vm:ComboCheckBox Grid.Column="1" ItemsSource="{Binding Path=Months}"
                    DefaultText="Select months"/&gt;
  </code></pre>
  
  <p>Months is ObservableNodeCollection.</p>
  
  <p>Template[I don't place here resources. they are the same, as at link]:</p>
  
  <pre><code>&lt;ComboBox   ItemsSource="{Binding ElementName=UserControl, Path=ItemsSource}"
              DataContext="{Binding ElementName=UserControl, Path=DataContext}"
              Text="{Binding Path=Text, Mode=OneWay, ElementName=UserControl, UpdateSourceTrigger=PropertyChanged}"
              Focusable="False"
              IsEditable="False"
              Loaded="CheckableCombo_Loaded"
  
              x:Name="CheckableCombo"
              SnapsToDevicePixels="True"
              OverridesDefaultStyle="True"
              ScrollViewer.HorizontalScrollBarVisibility="Auto"
              ScrollViewer.VerticalScrollBarVisibility="Auto"
              ScrollViewer.CanContentScroll="True"
              IsSynchronizedWithCurrentItem="True"
              MinWidth="120"
              MinHeight="20"
              &gt;
      &lt;ComboBox.ItemTemplate&gt;
          &lt;HierarchicalDataTemplate&gt;
                  &lt;CheckBox Margin="0" IsChecked="{Binding Path=IsSelected}"
                            Command="{Binding Path=CheckBoxStateChanged, ElementName=UserControl}" CommandParameter="{Binding}"
                            Content="{Binding Path=Title}" /&gt;
          &lt;/HierarchicalDataTemplate&gt;
      &lt;/ComboBox.ItemTemplate&gt;
      &lt;ComboBox.Template&gt;
          &lt;ControlTemplate TargetType="ComboBox"&gt;
              &lt;Grid&gt;
                  &lt;ToggleButton 
                                      Name="ToggleButton" 
                                      Template="{StaticResource ComboBoxToggleButton}" 
                                      Grid.Column="2" 
                                      Focusable="false"
                                      IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                                      ClickMode="Press"&gt;
                  &lt;/ToggleButton&gt;
                  &lt;ContentPresenter
                                      x:Name="Presenter"
                                      IsHitTestVisible="False" 
                                      Margin="3,3,23,3"
                                      VerticalAlignment="Center"
                                      HorizontalAlignment="Left"&gt;
                      &lt;ContentPresenter.Content&gt;
                          &lt;TextBlock TextTrimming="CharacterEllipsis"
                                              Text="{Binding Path=Text,Mode=OneWay,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}}" /&gt;
                      &lt;/ContentPresenter.Content&gt;
                  &lt;/ContentPresenter&gt;
                  &lt;TextBox x:Name="EditableTextBox"
                           Style="{x:Null}" 
                           Template="{StaticResource ComboBoxTextBox}" 
                           HorizontalAlignment="Left" 
                           VerticalAlignment="Center" 
                           Margin="3,3,23,3"
                           Focusable="True"
                           Background="Transparent"
                           Visibility="Hidden"
                           IsReadOnly="{TemplateBinding IsReadOnly}"/&gt;
                  &lt;Popup Name="Popup"
                         Placement="Bottom"
                         IsOpen="{TemplateBinding IsDropDownOpen}"
                         AllowsTransparency="True" 
                         Focusable="False"
                         PopupAnimation="Slide"&gt;
                      &lt;Grid Name="DropDown"
                            ShowGridLines="True"
                            SnapsToDevicePixels="True"                
                            MinWidth="{TemplateBinding ActualWidth}"
                            MaxHeight="{TemplateBinding MaxDropDownHeight}"&gt;
                          &lt;Border Focusable="False"
                                  x:Name="DropDownBorder"
                                  Background="{StaticResource WindowBackgroundBrush}"
                                  BorderThickness="1"
                                  BorderBrush="{StaticResource SolidBorderBrush}"/&gt;
                          &lt;ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True" DataContext="{Binding}"&gt;
                              &lt;StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle" KeyboardNavigation.ControlTabNavigation="Cycle" /&gt;
                          &lt;/ScrollViewer&gt;
                      &lt;/Grid&gt;
                  &lt;/Popup&gt;
              &lt;/Grid&gt;
              &lt;ControlTemplate.Triggers&gt;
                  &lt;Trigger Property="HasItems" Value="false"&gt;
                      &lt;Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/&gt;
                  &lt;/Trigger&gt;
                  &lt;Trigger Property="IsEnabled" Value="false"&gt;
                      &lt;Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/&gt;
                  &lt;/Trigger&gt;
                  &lt;Trigger Property="IsGrouping" Value="true"&gt;
                      &lt;Setter Property="ScrollViewer.CanContentScroll" Value="false"/&gt;
                  &lt;/Trigger&gt;
                  &lt;Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true"&gt;
                      &lt;Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/&gt;
                      &lt;Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/&gt;
                  &lt;/Trigger&gt;
                  &lt;Trigger Property="IsEditable" Value="true"&gt;
                      &lt;Setter Property="IsTabStop" Value="false"/&gt;
                      &lt;Setter TargetName="EditableTextBox" Property="Visibility" Value="Visible"/&gt;
                      &lt;Setter TargetName="Presenter" Property="Visibility" Value="Hidden"/&gt;
                  &lt;/Trigger&gt;
              &lt;/ControlTemplate.Triggers&gt;
          &lt;/ControlTemplate&gt;
      &lt;/ComboBox.Template&gt;
  &lt;/ComboBox&gt;
  </code></pre>
  
  <p>CodeBehind:</p>
  
  <pre><code>/// &lt;summary&gt;
  /// Interaction logic for ComboCheckBox.xaml
  /// &lt;/summary&gt;
  public partial class ComboCheckBox : UserControl
  {
      public ObservableNodeCollection ItemsSource 
      {
          get 
          { 
              return (ObservableNodeCollection)GetValue(ItemsSourceProperty); 
          } 
          set 
          {
              SetValue(ItemsSourceProperty, value);
              SetText();
          }
      }
  
      public static readonly DependencyProperty ItemsSourceProperty =
          DependencyProperty.Register("ItemsSource", typeof(ObservableNodeCollection), typeof(ComboCheckBox), new UIPropertyMetadata(null)); 
  
      /// &lt;summary&gt; 
      /// Gets or sets the text displayed in the ComboBox 
      /// &lt;/summary&gt; 
      public string Text 
      { 
          get
          { 
              return(string)GetValue(TextProperty); 
          }
          set 
          { 
              SetValue(TextProperty, value);
          } 
      } 
  
      public static readonly DependencyProperty TextProperty = 
          DependencyProperty.Register("Text", typeof(string), typeof(ComboCheckBox), new UIPropertyMetadata(string.Empty)); 
  
  
      /// &lt;summary&gt; 
      /// Gets or sets the text displayed in the ComboBox if there are no selected items 
      /// &lt;/summary&gt; 
      public string DefaultText 
      { 
          get
          {
              return(string)GetValue(DefaultTextProperty);
          }
          set
          {
              SetValue(DefaultTextProperty, value);
              SetText();
          }
      }
  
      public static readonly DependencyProperty DefaultTextProperty = 
          DependencyProperty.Register("DefaultText", typeof(string), typeof(ComboCheckBox), new UIPropertyMetadata(string.Empty)); 
  
      public ComboCheckBox()
      {
          InitializeComponent();
          this.SetText();
      }
  
      public ICommand CheckBoxStateChanged
      {
          get
          {
              return new Helpers.DelegateCommand&lt;Node&gt;((Node parameter) =&gt;
              {
                  if (parameter.IsSelectAllNode)
                  {
                      bool? isSelected = this.ItemsSource[0].IsSelected;
                      ItemsSource.ToList().ForEach(item =&gt; item.IsSelected = isSelected);
                  }
                  else
                  {
                      if (this.ItemsSource[0].IsSelectAllNode)
                      {
                          bool isAllTrue = true, isAllFalse = true;
                          for (int i = 1; i &lt; this.ItemsSource.Count; i++)
                          {
                              isAllTrue = isAllTrue &amp;&amp; this.ItemsSource[i].IsSelected.Value;
                              isAllFalse = isAllFalse &amp;&amp; !this.ItemsSource[i].IsSelected.Value;
                          }
                          if (isAllTrue)
                              this.ItemsSource[0].IsSelected = true;
                          else if (isAllFalse)
                              this.ItemsSource[0].IsSelected = false;
                          else
                              this.ItemsSource[0].IsSelected = null;
                      }
                  }
                  this.SetText();
              });
          }
      }
  
      private void SetText()
      {
          string answer = String.Empty;
          if (ItemsSource != null)
              answer = ItemsSource.ToString();
          if (String.IsNullOrWhiteSpace(answer))
              answer = this.DefaultText;
          this.Text = answer;
      }
  
      private void CheckableCombo_Loaded(object sender, RoutedEventArgs e)
      {
          this.SetText();
      }
  }
  </code></pre>
  
  <p>Node class:</p>
  
  <pre><code>public class Node : ObservableObject
  {
      public Node(string title, string header = "",  bool isSelectAllNode = false, bool? isSelected = false)
      {
          this.Title = title;
          if (String.IsNullOrEmpty(header))
              this.Header = title;
          else
              this.Header = header;
          this.IsSelectAllNode = isSelectAllNode;
          this.IsSelected = isSelected;
      }
      public string Header { get; set; }
      public string Title { get; set; }
      private bool? isSelected;
      private const string IsSelectedPropertyName = "IsSelected";
      public bool? IsSelected
      {
          get
          {
              return this.isSelected;
          }
          set
          {
              this.isSelected = value;
              this.OnPropertyChanged(IsSelectedPropertyName);
          }
      }
      public bool IsSelectAllNode { get; set; }
      public override string ToString()
      {
          return "123";//if miss it, the typeName will return.
      }
  }
  </code></pre>
  
  <p>ObservableNodeCollection:</p>
  
  <pre><code>public class ObservableNodeCollection : ObservableCollection&lt;Node&gt;
  {
      public ObservableNodeCollection()
      {
      }
      public ObservableNodeCollection(List&lt;Node&gt; list)
          : base(list)
      {
      }
      public ObservableNodeCollection(IEnumerable&lt;Node&gt; collection)
          : base(collection)
      {
      }
  
      public override string ToString()
      {
          string answer = String.Empty;
          if (this.Items != null)
          {
              StringBuilder outString = new StringBuilder();
              foreach (Node node in this.Items)
                  if (node.IsSelected == true &amp;&amp; !node.IsSelectAllNode)
                  {
                      outString.Append(node.Header);
                      outString.Append(", ");
                  }
              answer = outString.ToString().TrimEnd(new char[] { ',', ' ' });
          }
          return answer;
      }
  }
  </code></pre>
  
  <p><strong>EDIT 2:</strong></p>
  
  <p>Inside of the ViewModel constructor of the main window exist this code</p>
  
  <pre><code>        int i;
          //Initialize months for combobox
          this.Months = new ObservableNodeCollection(new List&lt;Node&gt;() { new Node("SelectAll", isSelectAllNode:true)});
  
          for (i=0; i &lt; DateTimeFormatInfo.CurrentInfo.MonthNames.Length; i++)
          {
              if (!String.IsNullOrEmpty(DateTimeFormatInfo.CurrentInfo.MonthNames[i]))
                  this.Months.Add(
                      new Node
                          (   
                              DateTimeFormatInfo.CurrentInfo.MonthNames[i], 
                              DateTimeFormatInfo.CurrentInfo.AbbreviatedMonthNames[i]
                          ));
          }
  </code></pre>
  
  <p>so, this.Months - is a ObservableNodeCollection, which have 1-st element is SelectAll, and other 12 elements is a months.</p>