Home > Enterprise >  ComboBox object doesn't display initial value
ComboBox object doesn't display initial value

Time:11-07

A ComboBox object with a data binding, when I propram like below, the content doesn't display until a selection operation made.

XAML:

<Window x:Class="Recipe_GUI.ComboboxTest"
        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"
        xmlns:local="clr-namespace:Recipe_GUI"
        xmlns:src="clr-namespace:RecipeLib;assembly=RecipeLib"
        mc:Ignorable="d"
        Title="ComboboxTest" Height="450" Width="800">
    <Window.Resources>
        <src:DataType x:Key="DataType"/>
    </Window.Resources>
    <Grid>
        <ComboBox HorizontalAlignment="Left" Margin="125,82,0,0" VerticalAlignment="Top" Width="120"  
                  x:Name="C01"
                  ItemsSource="{StaticResource ResourceKey=DataType}"
                  SelectedValue="{Binding Path=DataType}"/>
                  <!--SelectedValue="{Binding Path=Text, ElementName=T01}"/>-->     
        <TextBox Text="{Binding ElementName=C01, Path=SelectedIndex}" Margin="125,141,309,249"/>
        <TextBox Text="{Binding Path=DataType}" Margin="125,202,309,188" x:Name="T01"/>
    </Grid>
</Window>

enter image description here

When I change the code to binding the ComboBox to TextBox "T01"("T01" binding to the same object), the ComboBox initial value displayed as expected. The code and presentation like below.

        <ComboBox HorizontalAlignment="Left" Margin="125,82,0,0" VerticalAlignment="Top" Width="120"  
                  x:Name="C01"
                  ItemsSource="{StaticResource ResourceKey=DataType}"
                  SelectedValue="{Binding Path=Text, ElementName=T01}"/>
                  <!--SelectedValue="{Binding Path=DataType}"/>--> 

enter image description here

The other related code are like below.

XAML.CS:

using RecipeLib;
using System.Windows;

namespace Recipe_GUI
{
    /// <summary>
    /// Interaction logic for ComboboxTest.xaml
    /// </summary>
    public partial class ComboboxTest : Window
    {
        Param param = new Param();
        public ComboboxTest()
        {
            InitializeComponent();
            DataContext = param;
        }
    }
}

Class Param:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;


namespace RecipeLib
{
    public class Param : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private Enum_DataType dataType;
        public Enum_DataType DataType
        {
            get { return dataType; }
            set
            {
                dataType = value;
                OnPropertyChanged("DataType");
            }
        }
        public Param()
        {
            DataType = Enum_DataType.Float;
        }
    }
}

Enum_DataType and DataType:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace RecipeLib
{
    public enum Enum_DataType : int
    {
        Float = 0,
        Integer = 1,
        Enumeration = 2,
        Bitmask = 3,
        Time = 4
    }

    public class DataType : ObservableCollection<string>
    {
        public DataType() : base()
        {
            foreach (var item in Enum.GetNames(typeof(Enum_DataType)))
            {
                Add(item);
            }
        }
    }
}

Please help answer why the first method doesn't work for the initial value, and how to fix? Thank you in advance!

CodePudding user response:

Old Code

<ComboBox HorizontalAlignment="Left" Margin="125,82,0,0" 
              VerticalAlignment="Top" Width="120"  
              x:Name="C01"
              ItemsSource="{StaticResource ResourceKey=DataType}"
              SelectedValue="{Binding Path=DataType}"/>

it's an assumption so if anyone can correct me then please do it. I believe the ComboBox has a "Text" property and in this case, you are binding an enum so you need a converter to convert the value from enum to string. so I added a converter and it worked.

Additional: each ComboBoxItem has a "Content" property which is a string type so when you choose any of the items the ComboBox "Text" property is set automatically. that's why it works when you select any of the items. the same logic applies to your code where you bound the text property of Textblock to ComboBox property "SelectedValue"

Updated Code

Here are some modifications I did to your existing code

Converter class

Option: I named it "EnumToStringConverter" but you can name this class whatever you want

public class EnumToStringConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Enum.GetNames(value.GetType()).ElementAt((int)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Enum.Parse(targetType, value.ToString());
    }
  }

XAML

<Window.Resources>
    <local:DataType x:Key="DataType"/>
    <local:EnumToStringConverter x:Key="EnumConverter" />
</Window.Resources>

<ComboBox HorizontalAlignment="Left" Margin="125,82,0,0" VerticalAlignment="Top" Width="120"  
              x:Name="C01"
              ItemsSource="{StaticResource DataType}"
              SelectedValue="{Binding DataType, Converter={StaticResource EnumConverter}}" />
 
  • Related