How Can I save a ComboBox selected value in settings file when it has dynamic content in WPF?

MERUN KUMAR MAITY 636 Reputation points
2023-01-17T12:01:51.96+00:00

I have a WPF application where I use many ComboBox controls. Most of the time I save application user settings in the Settings file, though many people use JSON to do that work but I think the default Settings file in WPF application is provided by Microsoft is far more better to use and robust also.

Now come in to the main topic, suppose if I want to save the Combobox last selected value before my application is closed then I just create a user settings and give the type "string" and declare it in the window closing event.

Here is the example, suppose I create a user settings name "ComboBoxStateThree" and give the type "string".

so, the code will be

Properties.Settings.Default.ComboBoxStateThree = cmb1.SelectedValue.ToString();

and if I want to do through pure XAML then the code of the Binding is

SelectedValuePath="Content" SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=ComboBoxStateThree, Mode=TwoWay}"

Both methods works great but the XAML approach is too much fast. And another important point is, I save the user Settings file in a separate folder name Properties.

I can save any ComboBox value by those method. But theres a catch. This method only works when the Combobox have predefined static values but if the Combobox itemsource bind to ObservableCollection or any listcollection view (List<>) then it is not working anymore.

One of my Combobox itemsource binded to a List and a added the itemsource from code behind.

Here is some code snippet.

 Marshal.ReleaseComObject(pDeviceCollection);
                ListCollectionView lcv = new(devices);
 lcv.GroupDescriptions.Add(new PropertyGroupDescription("Direction"));
 cmb1.ItemsSource = lcv;

my Combobox name is cmb1 in this case.

My question is, How Can I save the cmb1 selected value in settings file because in this case the ItemSource is the List and the List has different values depending upon situation, in a single sentence the CoboBox has dynamic content.

Developer technologies | Windows Presentation Foundation
Developer technologies | XAML
Developer technologies | C#
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Hui Liu-MSFT 48,681 Reputation points Microsoft External Staff
    2023-01-18T08:30:13.8733333+00:00

    I try to reproduce the problem environment and rewrite the OnClosing method. It can work. You could check it out.

    Here's saving the SelectedItem to a setting file.

    enter image description here

    <Window x:Class="SelectedItemSave.MainWindow"
           ...
            xmlns:local="clr-namespace:SelectedItemSave"
             xmlns:p="clr-namespace:SelectedItemSave.Properties"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <StackPanel>
                <Button x:Name="btn" Click="btn_Click" Height="30" Content=" add item"/>
                <ComboBox Name="cmb1" Height="50" ItemsSource="{Binding Icv}"  DisplayMemberPath="Name"   
                      SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=p, Mode=TwoWay}" SelectedValuePath="Id"/>
            </StackPanel>
        </Grid>
    </Window>
    

    Codebehind:

    
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Data;
    
    namespace ComboBoxSaveSelectedItem
    {
        public partial class MainWindow : Window, INotifyPropertyChanged
        {
            public int flag = 2;
            public MainWindow()
            {
    
                InitializeComponent();
                DataContext = this;
                if (flag != null)
                {
                    string sIdDefaultRender = null;
    
                    devices.Add(new AudioDevice() { Name = "System default", Direction = "Playback", Id = sIdDefaultRender, Default = true });
    
                    devices.Insert(devices.Count - 0, new AudioDevice() { Name = "Selected application ...", Direction = "Recording", Id = "Idlast", Default = false });
    
                    Icv = new ListCollectionView(devices);
                    Icv.GroupDescriptions.Add(new PropertyGroupDescription("Direction"));
    
                    this.cmb1.ItemsSource = Icv;
                }
                DataContext = this;
            }
            private ObservableCollection<AudioDevice> devices = new ObservableCollection<AudioDevice>();
            public ObservableCollection<AudioDevice> Devices
            {
                get { return devices; }
                set
                {
                    if (devices != value)
                    {
                        devices = value;
                        OnPropertyChanged("Devices");
                    }
                }
            }
            private AudioDevice selectedItem;
    
            public AudioDevice SelectedItem
            {
                get { return selectedItem; }
                set
                {
                    selectedItem = value;
                    OnPropertyChanged("SelectedItem");
                }
            }
            private ICollectionView icv;
    
            public ICollectionView Icv
            {
                get { return icv; }
                set
                {
                    icv = value;
                    OnPropertyChanged("Icv");
                }
            }
           
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged([CallerMemberName] string name = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
    
            protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
            {
                Properties.Settings.Default.Save();
                base.OnClosing(e);
            }
    
    
        }
        public class AudioDevice
        {
            public string Id { get; set; }
            public string Name { get; set; }
            public string Direction { get; set; }
            public bool Default { get; set; }
            public AudioDevice() { }
        }
    }
    
    

    The result:

    5

    -

    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our [documentation][5] to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.