使用 MVVM (C# WPF),您如何在应用程序初始化时将设置显示到各自的控件中?

With MVVM (C# WPF) how do you display settings into their respective controls upon app initialization?

我有 3 个组合框绑定到名为 ARDAR 的对象,其属性为 ARFlagDARFlagConfirmedFlag。当从 ComboBox 中选择一个标志时,其 ID 将保存在设置中 (Properties.Settings.Default.ARFlag = aRFlag.flag1;)。

应用程序启动时,会通过 XAML 创建 ARDAR 对象的实例。对象的构造函数检查非零值的设置,如果有值 (if (Properties.Settings.Default.ARFlag != 0) ARFlag = sa.flags.Where(f => f.flag1 == Properties.Settings.Default.ARFlag).FirstOrDefault();)

则更新 属性

这会触发 OnPropertyChanged 方法,我认为该方法会更新组合框,然后显示已保存设置的选择。但是,在初始化应用程序时,组合框留空。我确保 ARDAR 的属性实际上已更改为其各自的设置,并且 OnPropertyChanged 实际上正在触发。那么,我错过了什么?如何让组合框显示它们保存的设置?
这是我的 XAML & C# 代码:

       public class ARDAR : INotifyPropertyChanged
{
    public ARDAR()
    {
        var sa = new SALinqDataContext();

        if (Properties.Settings.Default.ARFlag != 0) ARFlag = sa.flags.Where(f => f.flag1 == Properties.Settings.Default.ARFlag).FirstOrDefault();
        if (Properties.Settings.Default.DARFlag != 0) DARFlag = sa.flags.Where(f => f.flag1 == Properties.Settings.Default.DARFlag).FirstOrDefault();
        if (Properties.Settings.Default.ConfirmedFlag != 0) ConfirmedFlag = sa.flags.Where(f => f.flag1 == Properties.Settings.Default.ConfirmedFlag).FirstOrDefault();            
    }

    flag aRFlag;
    flag dARFlag;
    flag confirmedFlag;

    public flag ARFlag
    {
        get
        {
            return aRFlag;
        }

        set
        {
            aRFlag = value;
            OnPropertyChanged("ARFlag");
            Properties.Settings.Default.ARFlag = aRFlag.flag1;
            Properties.Settings.Default.Save();
        }
    }

    public flag DARFlag
    {
        get
        {
            return dARFlag;
        }

        set
        {
            dARFlag = value;
            OnPropertyChanged("DARFlag");
            Properties.Settings.Default.DARFlag = dARFlag.flag1;
            Properties.Settings.Default.Save();
        }
    }

    public flag ConfirmedFlag
    {
        get
        {
            return confirmedFlag;
        }

        set
        {
            confirmedFlag = value;
            OnPropertyChanged("ConfirmedFlag");
            Properties.Settings.Default.ConfirmedFlag = confirmedFlag.flag1;
            Properties.Settings.Default.Save();
        }
    }



    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

以及相关的XAML:

      <Window.Resources>
    <luke:ARDAR x:Key="ARDAR"/>
    <luke:ocSAFlags x:Key="ocSAFlags" />
</Window.Resources>
<TabControl>
    <TabItem Header="Retention">
        <TabControl>
            <TabItem Header="Renewals">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <ToolBar Grid.Row="0">
                        <StackPanel Orientation="Horizontal" DataContext="{StaticResource ARDAR}">
                            <Label Content="AR Flag" />
                            <ComboBox Width="120"
                                      ItemsSource="{StaticResource ocSAFlags}"
                                      DisplayMemberPath="flag_desc"
                                      SelectedItem="{Binding ARFlag}"
                                      />
                            <Label Content="DAR Flag" />
                            <ComboBox Width="120"
                                      ItemsSource="{StaticResource ocSAFlags}"
                                      DisplayMemberPath="flag_desc"
                                      SelectedItem="{Binding DARFlag}" />
                            <Label Content="Conf Flag" />
                            <ComboBox Width="120"
                                      ItemsSource="{StaticResource ocSAFlags}"
                                      DisplayMemberPath="flag_desc"
                                      SelectedItem="{Binding ConfirmedFlag}"/>
                        </StackPanel>
                    </ToolBar>
                </Grid>
            </TabItem>
        </TabControl>
    </TabItem>
</TabControl>

编辑:我还应该显示提供 ocSAFlags 的代码,以防与解决方案相关。

        public class ocSAFlags : ObservableCollection<flag>
{
    public ocSAFlags()
    {
        var sa = new SALinqDataContext();
        var flags = sa.flags.Where(f => f.available == true)
                        .OrderBy(f => f.flag_desc);
        foreach (flag f in flags) Add(f);
    }
}

阻止 ComboBox 显示信息的问题最终与程序初始化时的加载顺序无关。 真正的问题是我的 XAML 实例化了 ocSAFlags 的一个实例,它填充了 ComboBox,当 ARDAR 被初始化并设置值 (flag) 时绑定属性,这些值是等效的,但与实际值不同 flag。 因此,我的解决方案实际上最终是将 ocSAFlags 设为 Static Class,并使用它来提供 属性 作为 ComboBoxesItemsSource 作为以及查找存储在设置中的 ID 的 flag 的 linq 查询的 'source'。

XAML:我从资源中删除了行 <luke:ocSAFlags x:Key="ocSAFlags" />。我更改了 ItemsSources:ItemsSource="{Binding Source={x:Static luke:ocSAFlags.OCFlag},Mode=OneWay}"

这是静态的 class:

public static class ocSAFlags
{
    static private ObservableCollection<flag> oCFlag = getSAFlags();

    private static ObservableCollection<flag> getSAFlags()
    {
        var x = new ObservableCollection<flag>();
        var sa = new SALinqDataContext();
        var flags = sa.flags.Where(f => f.available == true)
                        .OrderBy(f => f.flag_desc);
        foreach (flag f in flags) x.Add(f);
        return x;
    }

    public static ObservableCollection<flag> OCFlag
    {
        get
        {
            return oCFlag;
        }     
    }
}