我无法弄清楚:使用ComboBox冒泡SelectionChanged事件的用户控件

时间:2011-03-10 18:42:52

标签: wpf wpf-controls

我似乎无法让这个工作。使用滑块和任何通过简单类型的控件都很容易,但我似乎无法弄清楚如何使用ComboBoxItem冒泡ComboBox SelectionChanged。

这总是失败:

InnerException:System.TypeInitializationException                                      Message ='Module.Dashboard.KpiComboBox'的类型初始值设定项引发了异常。                                      类型名= Module.Dashboard.KpiComboBox                                      InnerException:System.ArgumentException                                           消息=“值”属性的默认值不能绑定到特定线程。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using PA.DPW.PACSES.CAL.Infrastructure;

namespace Module.Dashboard
{
    /// <summary>
    /// Interaction logic for KpiComboBox.xaml
    /// </summary>
    public partial class KpiComboBox : UserControl
    {
        public KpiComboBox()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Called to bind the proper KPIs to the cboKpi, according to which View name you pass
        /// </summary>
        /// <param name="viewName">Use Constants viewnames</param>
        /// <example>
        /// kpiComboBox.BindComboBox(Constants.CountyMapViewName);
        /// </example>
        public void BindComboBox(string viewName)
        {
            List<KPICodeDescription> lstKpi = null;

            switch (viewName)
            {
                case Constants.CountyMapViewName:
                    lstKpi = UtilityHelper.GetKpiList(Constants.CountyMapViewName);
                    break;
                case Constants.CountyRankingsViewName:
                    lstKpi = UtilityHelper.GetKpiList(Constants.CountyRankingsViewName);
                    break;
                case Constants.StateMapViewName:
                    lstKpi = UtilityHelper.GetKpiList(Constants.StateMapViewName);
                    break;
                case Constants.StateRankingsViewName:
                    lstKpi = UtilityHelper.GetKpiList(Constants.StateRankingsViewName);
                    break;
                default:
                    break;
            }

            if (lstKpi != null)
            {
                cboKpi2.ItemsSource = lstKpi;
                cboKpi2.DisplayMemberPath = "KPIDescription";
                cboKpi2.SelectedValuePath = "KPICode";
            }
        }

        // Dependency Object for Bubbling

        private ComboBoxItem value;

        public ComboBoxItem Value
        {
            get { return (ComboBoxItem)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        private static void OnSelectionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            KpiComboBox cboControl = (KpiComboBox)sender;

            cboControl.value = (ComboBoxItem)args.NewValue;
            cboControl.OnSelectionChanged((ComboBoxItem)args.OldValue, (ComboBoxItem)args.NewValue);
        }

        public static readonly DependencyProperty ValueProperty =
           DependencyProperty.Register("Value", typeof(object), typeof(KpiComboBox), new PropertyMetadata(new Object(), OnSelectionChanged));
           //DependencyProperty.Register("Value", typeof(ComboBoxItem), typeof(KpiComboBox));

        // Event Bubbling

        public static readonly RoutedEvent SelectionChangedEvent =
           EventManager.RegisterRoutedEvent("SelectionChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(KpiComboBox));


        // Provide CLR accessors for the event
        public event RoutedPropertyChangedEventHandler<ComboBoxItem> SelectionChanged
        {
            add { AddHandler(SelectionChangedEvent, value); }
            remove { RemoveHandler(SelectionChangedEvent, value); }
        }

        private void OnSelectionChanged(ComboBoxItem oldValue, ComboBoxItem newValue)
        {
            RoutedPropertyChangedEventArgs<ComboBoxItem> args = new RoutedPropertyChangedEventArgs<ComboBoxItem>(oldValue, newValue);
            args.RoutedEvent =  KpiComboBox.SelectionChangedEvent;
            RaiseEvent(args);
        }

        // This method raises the SelectionChanged event
        void RaiseSelectionChangedEvent()
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(KpiComboBox.SelectionChangedEvent);
            RaiseEvent(newEventArgs);
        }

        private void cboKpi2_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            MessageBox.Show("Hello from UC");
            RaiseSelectionChangedEvent();
            //cboKpi2.SelectedItem =;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

嗯,简短的回答是你尝试更换

DependencyProperty.Register("Value", typeof(object), typeof(KpiComboBox), new PropertyMetadata(new Object(), OnSelectionChanged));

DependencyProperty.Register("Value", typeof(ComboBoxItem), typeof(KpiComboBox), new PropertyMetadata(null, OnSelectionChanged));

但是,我不明白为什么这是必要的 - 不是ComboBox.SelectionChanged 已经路由事件?这意味着你可以在任何级别监听它,无论实际控制的类型如何,如果在层次结构的某个地方你有ComboBox?此外,如果您使用MVVM,还有更简单的方法。继续,问我更多,我可以继续几个小时:)