【问题标题】:WPF - Force Binding on Invisible ComboBoxWPF - 强制绑定不可见的组合框
【发布时间】:2019-08-17 05:20:52
【问题描述】:

我有一个包含多个用户控件的 WPF 窗口,其中一些是不可见的(可见性 = 隐藏)。其中一个控件有一个具有 ItemsSource 绑定的 ComboBox,我想在加载窗口/控件时预设其选定的项目。

但是,在组合框可见之前,似乎不会应用绑定。当我设置 SelectedItem 属性并在调试器中遇到断点时,我注意到 ItemsSource 在那一刻为空。有没有办法强制 WPF 应用数据绑定并在组合框保持不可见时填充组合框?

可重现的例子:

MainWindow.xaml

<Window x:Class="HiddenComboBoxBinding.MainWindow"
        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:HiddenComboBoxBinding"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Border x:Name="comboboxParent" Visibility="Collapsed">
            <ComboBox x:Name="cmbSearchType" SelectedIndex="0" ItemsSource="{Binding SearchTypeOptions}" DisplayMemberPath="Name" SelectionChanged="cmbSearchType_SelectionChanged" />
        </Border>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace HiddenComboBoxBinding
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ViewModel viewModel { get; set; } = new ViewModel();

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = viewModel;

            // Add some or all of our search types - in the real code, there's some business logic here
            foreach (var searchType in SearchType.AllSearchTypes)
            {
                viewModel.SearchTypeOptions.Add(searchType);
            }

            // Pre-select the last option, which should be "Bar"
            cmbSearchType.SelectedItem = SearchType.AllSearchTypes.Last();
        }

        private void cmbSearchType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }
    }
}

ViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HiddenComboBoxBinding
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<SearchType> SearchTypeOptions { get; set; } = new ObservableCollection<SearchType>();

        #region INotifyPropertyChanged Members
        private void NotifyPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }

    public class SearchType
    {
        // Source list of Search Types
        private static List<SearchType> _AllSearchTypes;
        public static List<SearchType> AllSearchTypes
        {
            get
            {
                if(_AllSearchTypes == null)
                {
                    _AllSearchTypes = new List<SearchType>();
                    _AllSearchTypes.Add(new SearchType() { Name = "Foo" });
                    _AllSearchTypes.Add(new SearchType() { Name = "Bar" });
                }
                return _AllSearchTypes;
            }
        }

        // Instance properties - for the purposes of a minimal, complete, verifiable example, just one property
        public string Name { get; set; }
    }
}

【问题讨论】:

  • 试试Visibility = Visibility.Collapsed 而不是Visibility.Hidden 也许会有所作为。
  • 当 ItemsSource == null(而不是空)时,您在错误的时间设置了 SelectedItem。为此创建一个minimal reproducible example
  • 折叠的可见性有相同的结果
  • 也加了一个例子

标签: c# wpf


【解决方案1】:

我能够找出问题所在。设置 SelectedItem 确实有效(即使当时 ItemsSource 为空),但在 XAML 中,ComboBox 具有 SelectedIndex="0" 并且优先于在代码隐藏中设置的 SelectedItem。

【讨论】:

  • 在您的示例代码中,InitializeComponent();this.DataContext = viewModel; 之前。如果您在设置SelectedItem 时交换这两个ItemSource,则不会是null。但是,在InitializeComponent doesn't seem to be a good idea. 之前设置DataContext
猜你喜欢
  • 2012-06-18
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
相关资源
最近更新 更多