【问题标题】:Set the SelectionChanged event of a ComboBox while binding its SelectedItem and ItemsSource in XAML在 XAML 中绑定其 SelectedItem 和 ItemsSource 时设置 ComboBox 的 SelectionChanged 事件
【发布时间】:2015-09-30 16:49:50
【问题描述】:

我正在尝试设置一个 ComboBox,其选项绑定自字符串列表,其默认选择值绑定自设置,并且其选择的事件处理程序已更改。

我想像这样使用 XAML 来配置它:

    <ComboBox Name="RoutesComboBox"
              ItemsSource="{Binding Routes}"
              SelectedItem="{Binding DefaultRoute}" 
              SelectionChanged="RouteFilter_SelectionChanged" />

但是当我在启动时这样做时会抛出错误:

未处理的类型异常 'System.Reflection.TargetInvocationException' 发生在 PresentationFramework.dll

如果我只在 XAML 中执行其中一些操作,则可以在 C# 中以编程方式设置 SelectionChanged 事件或 ItemsSource,如下所示,它可以正常工作。但是我有很多这样的组合框,所以我宁愿直接在 XAML 中进行。

<ComboBox Name="RoutesComboBox"
          ItemsSource="{Binding Routes}"
          SelectedItem="{Binding DefaultRoute}" />

使用这个 C#:

public IEnumerable<string> Routes
{
    get { return LubricationDatabase.GetRoutes(); }
}

public string DefaultRoute
{
    get { return MySettings.Default.DefaultRoute; }
    set { } /* side question: without this, it throws a parse exception. Any idea why? */
}

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

     RoutesComboBox.SelectionChanged += RouteFilter_SelectionChanged;
 }

我也试过here找到的解决方案:

private string _defaultRoute;
public string DefaultRoute
{
    get { return MySettings.Default.DefaultRoute; }
    set
    {
        if (_defaultRoute != value)
        {
            _defaultRoute = value;

            // this fires before `SelectedValue` has been 
            // updated, and the handler function uses that,
            // so I manually set it here.
            RoutesComboBox.SelectedValue = value;
            SelectionChangedHandler(); 
        }
    }
}

这没关系,但是当我可以以编程方式分配 SelectionChanged 事件时,它相当庞大并且可能比值得做的工作更多。

如果可能的话,我想再次使用 XAML 来完成这一切,因为我有很多这样的 ComboBox,并且在 C# 中像这样初始化它们看起来很糟糕。

有什么想法吗?

【问题讨论】:

    标签: c# wpf xaml mvvm data-binding


    【解决方案1】:

    当您不打算在用户更改其选择时更新项目时,为什么要与SelectedItem 绑定?不确定您的事件处理程序在做什么,但我有一个您想要的工作解决方案。

    简而言之,您需要使用支持字段跟踪DefaultRoute。此外,当您的视图模型中的选定项目发生变化时,您需要通知 UI;顺便说一句,这似乎是你没有做的事情,MVVM。如果您计划以某种方式更新视图,您应该只挂钩到选择更改事件。所有其他更改都应在您的视图模型中处理DefaultRoutesetter

    XAML

    <ComboBox Name="RoutesComboBox"
          ItemsSource="{Binding Routes}"
          SelectedItem="{Binding DefaultRoute}" 
          SelectionChanged="RouteFilter_SelectionChanged" />
    

    代码

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public IEnumerable<string> Routes
        {
            get
            {
                return new string[] { "a", "b", "c", "d" };
            }
        }
    
        public string DefaultRoute
        {
            get
            {
                return _defaultRoute;
            }
            set
            {
                _defaultRoute = value;
                // Handle saving/storing setting here, when selection has changed
                //MySettings.Default.DefaultRoute = value;
                NotifyPropertyChanged();
            } 
        }
    
        public MainWindow()
        {
            this.DataContext = this;
            InitializeComponent();
    
            DefaultRoute = MySettings.Default.DefaultRoute;
        }
    
        private string _defaultRoute;
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    
        private void RouteFilter_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
    
        }
    }
    
    public static class MySettings
    {
        public static class Default
        {
            public static string DefaultRoute = "a";
        }
    }
    

    【讨论】:

    • 哇!你搞定了,谢谢。为了回答您的问题,我不希望用户只是更改他们上次选择的路线来更改他们的默认路线。这也照顾了我手动做的另一件事,即保持不同组合框的选定项目与相同的项目同步。如您所见,我是 MVVM 和绑定的新手。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 2014-12-10
    • 2013-10-22
    • 2012-06-07
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 2016-05-15
    相关资源
    最近更新 更多