Я не могу понять: пользовательский элемент управления с ComboBox всплывает событие SelectionChanged - PullRequest
0 голосов
/ 10 марта 2011

Я не могу заставить это работать. Это легко сделать с помощью ползунков и любых элементов управления, которые передают простые типы, но я не могу понять, как создать выделение ComboBox, измененное с помощью его ComboBoxItem.

Это всегда терпит неудачу с:

InnerException: System.TypeInitializationException Сообщение = инициализатор типа для «Module.Dashboard.KpiComboBox» выдал исключение. TypeName = 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 голосов
/ 10 марта 2011

Ну, краткий ответ: попытаетесь ли вы заменить

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. Давай, спроси меня больше, я мог бы идти часами:)

...