简体   繁体   English

组合框初始化

[英]Combobox initialization

I'm using a ComboBox to display a list of ZoomLevels (eg normal, large, xxl), the selected ZoomLevel is bound to the variable "ZoomLevel" in my MainViewModel. 我正在使用ComboBox显示ZoomLevels列表(例如,普通,大,xxl),所选的ZoomLevel绑定到MainViewModel中的变量“ ZoomLevel”。

<ComboBox ItemsSource="{Binding ZoomLevels}" 
          SelectedItem="{Binding ZoomLevel}"
          IsSynchronizedWithCurrentItem="True"
          DisplayMemberPath="Name"
          SelectedValuePath="Name"/>

On application start, the initial ZoomLevel is loaded from the settings and might be set to "xxl", eg 在应用程序启动时,将从设置中加载初始的ZoomLevel,并且可以将其设置为“ xxl”,例如

My problem is that during initialization of the ComboBox, the setter of "ZoomLevel" is called with the first ZoomLevel in the bound collection "ZoomLevels". 我的问题是,在ComboBox初始化期间,将使用绑定集合“ ZoomLevels”中的第一个ZoomLevel调用“ ZoomLevel”的设置器。

This overwrites the value for "ZoomLevel" loaded from the settings and it's always the first ZoomLevel that is selected in the combobox. 这将覆盖从设置加载的“ ZoomLevel”的值,并且它始终是组合框中选择的第一个ZoomLevel。

What is the problem here? 这里有什么问题? If I remove IsSynchronizedWithCurrentItem , then the ZoomLevel is initialized correctly. 如果我删除IsSynchronizedWithCurrentItem ,则ZoomLevel将正确初始化。 However, the Combobox is then not in sync with the currently selected ZoomLevel, which it should be. 但是,组合框随后不会与当前应选择的ZoomLevel同步。

EDIT: relevant code from my MainViewModel: 编辑:来自我的MainViewModel的相关代码:

public class ZoomLevel
{
    public string Name { get; set; }
    public double ZoomLevelValue { get; set; } 
}

    public MainViewModel() 
    {
     ...
            // Load zoom level
            var userDefinedZoom = ZoomLevels.FirstOrDefault(x => x.ZoomLevelValue == Settings.Default.ZoomLevelValue);
            ZoomLevel = userDefinedZoom ?? ZoomLevels[0];
     }

    /// <summary>
    /// Zoom level of application, initialized in the constructor
    /// </summary>
    private ZoomLevel _zoomLevel;
    public ZoomLevel ZoomLevel
    {
        get { return _zoomLevel; }
        set
        {
            _zoomLevel = value;

            Settings.Default.ZoomLevelValue = value.ZoomLevelValue;
            Settings.Default.Save();

            RaisePropertyChanged("ZoomLevel");
        }


    /// <summary>
    /// all available zoom levels
    /// </summary>
    public ObservableCollection<ZoomLevel> ZoomLevels
    {
        get
        {
            return new ObservableCollection<ZoomLevel>()
            {
                new ZoomLevel() { Name="normal", ZoomLevelValue = 1 },
                new ZoomLevel() { Name="large", ZoomLevelValue = 1.2 },
                new ZoomLevel() { Name="xxl", ZoomLevelValue = 1.4 },
            };
        }
    }

The SelectedItem must be a member of the ItemsSource collection. SelectedItem必须是ItemsSource集合的成员。

You should therefore initialize the ZoomLevel property with that instance of the ZoomLevels that corresponds to the current default value: 因此,您应该使用与当前默认值相对应的ZoomLevels实例来初始化ZoomLevel属性:

public MainViewModel()
{
    ZoomLevels = new List<ZoomLevel>()
    {
        new ZoomLevel { Name = "normal", ZoomLevelValue = 1 },
        new ZoomLevel { Name = "large", ZoomLevelValue = 1.2 },
        new ZoomLevel { Name = "xxl", ZoomLevelValue = 1.4 },
    };

    // here
    ZoomLevel = ZoomLevels.FirstOrDefault(
        z => z.ZoomLevelValue == Settings.Default.ZoomLevelValue);
}

public List<ZoomLevel> ZoomLevels { get; private set; }

Note also that if the ZoomLevels collection never changes, it is not necessary that it is an ObservableCollection. 还要注意,如果ZoomLevels集合从不改变,则不一定是ObservableCollection。

Besides that, setting the SelectedValuePath of the ComboBox only makes sense in conjunction with SelectedValue . 除此之外,设置ComboBox的SelectedValuePath仅与SelectedValue结合使用才有意义。 As you are using SelectedItem , it is redundant. 当您使用SelectedItem ,它是多余的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM