silverlight combox 绑定 source 时, 处理空值问题。

来源:互联网 发布:华信软件技术有限公司 编辑:程序博客网 时间:2024/06/05 10:21

参考 : http://www.codeproject.com/Articles/202523/Silverlight-Combobox

 

 public class ComboBoxHelper
    {
        private static object _SyncLock = new object();
        private static Dictionary<int, Binding> _BindingsByHashCode = new Dictionary<int, Binding>();

        /// <summary>
        /// Searches for all ComboBoxes below the provided element and subscribes them to the binding patch solution
        /// </summary>
        /// <param name="rootElement">The root UI element to search</param>
        public static void FixSelectedValueBindings(UIElement rootElement)
        {
            List<ComboBox> comboBoxes = new List<ComboBox>();
            GetAllComboBoxes(rootElement, comboBoxes);

            foreach (ComboBox comboBox in comboBoxes)
            {
                FixSelectedValueBindings(comboBox);
            }
        }

        /// <summary>
        /// Subscribes the supplied combobox to the binding patch solution
        /// </summary>
        /// <param name="rootElement">The root UI element to search</param>
        public static void FixSelectedValueBindings(ComboBox comboBox)
        {
            if (!IsControlRegistered(comboBox))
            {
                //subscribe to events
                comboBox.SelectionChanged += new SelectionChangedEventHandler(comboBox_SelectionChanged);
                comboBox.Unloaded += new RoutedEventHandler(comboBox_Unloaded);

                //save the initial binding
                SaveBinding(comboBox);
            }
        }

        /// <summary>
        /// Traveses the UI tree recursively and finds all comboboxes
        /// </summary>
        /// <param name="element">The root of the ui tree</param>
        /// <param name="comboBoxes">The list of comboxes, this list should be empty initially and will be populated recursively.</param>
        private static void GetAllComboBoxes(UIElement element, List<ComboBox> comboBoxes)
        {
            if (element == null)
                return;

                int childCount = VisualTreeHelper.GetChildrenCount(element);
                for (int i = 0; i < childCount; i++)
                {
                    UIElement child = (UIElement)VisualTreeHelper.GetChild(element,i);
                    if (child is ComboBox)
                    {
                        comboBoxes.Add((ComboBox)child);
                    }
                    else
                    {
                        GetAllComboBoxes(child, comboBoxes);
                    }
                 }
          }

        /// <summary>
        /// Event handler subscribed to all comboxes participating in this patch
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox comboBox = (ComboBox)sender;

            //if the selected value is being set to null
            if (comboBox.SelectedValue == null)
            {
                //get the saved binding and re-apply it
                 Binding binding = GetSavedBinding(comboBox.GetHashCode());
                 if (binding != null)
                 {
                     comboBox.SetBinding(ComboBox.SelectedValueProperty, binding);
                 }
            }
            else
            {
                //if the binding is not null, save it to the cache
                SaveBinding(comboBox);
            }
        }

        /// <summary>
        /// Checks if a combox is already participating in the solution.  Comboxes are identified by hashcode.
        /// </summary>
        /// <param name="comboBox"></param>
        /// <returns></returns>
        private static bool IsControlRegistered(ComboBox comboBox)
        {
            lock (_SyncLock)
            {
                return _BindingsByHashCode.ContainsKey(comboBox.GetHashCode());
            }
        }

        /// <summary>
        /// Combobox Unload event handler, unsubscribes the combox from our events and clears it out of the cache.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void comboBox_Unloaded(object sender, RoutedEventArgs e)
        {
            ComboBox comboBox = (ComboBox)sender;
            comboBox.Unloaded -= comboBox_Unloaded;
            comboBox.SelectionChanged -= comboBox_SelectionChanged;
            RemoveSavedBinding(comboBox.GetHashCode());
        }


        private static void RemoveSavedBinding(int objectHashCode)
        {
            lock (_SyncLock)
            {
                if (_BindingsByHashCode.ContainsKey(objectHashCode))
                {
                    _BindingsByHashCode.Remove(objectHashCode);
                }
            }
        }

        private static void SaveBinding(ComboBox comboBox)
        {
            BindingExpression bindingExpression = comboBox.GetBindingExpression(ComboBox.SelectedValueProperty);
            if (bindingExpression != null)
            {
                SaveBinding(comboBox.GetHashCode(), bindingExpression.ParentBinding);
            }
        }

        private static void SaveBinding(int objectHashCode, Binding binding)
        {
            if (binding == null)
                return;
            lock (_SyncLock)
            {
                if (_BindingsByHashCode.ContainsKey(objectHashCode))
                {
                    _BindingsByHashCode[objectHashCode] = binding;
                }
                else
                {
                    _BindingsByHashCode.Add(objectHashCode, binding);
                }
            }
        }

        private static Binding GetSavedBinding(int objectHashCode)
        {
            Binding binding = null;
            lock (_SyncLock)
            {
                if (_BindingsByHashCode.ContainsKey(objectHashCode))
                {
                    binding = _BindingsByHashCode[objectHashCode];
                }
            }
            return binding;
        }

    }

 

然后在有 combox 的页面里,后台做些处理。

 

 public partial class CarrierWindow : ChildWindow
    {


        TermTypeView TermTypeViewModel = null;
        JTCodeDictionaryView JTCodeDictionaryView = null;
        public CarrierWindow()
        {
            InitializeComponent();

         //设置数据源
             initDictionaryData();

      ///
            this.LayoutUpdated += new EventHandler(CarrierWindow_LayoutUpdated);

        }

   ///

        void CarrierWindow_LayoutUpdated(object sender, EventArgs e)
        {
            ComboBoxHelper.FixSelectedValueBindings(this);
        }

        private void ChildWindow_Loaded(object sender, RoutedEventArgs e)
        {
            this.MainTab.DataContext = this.DataSource;
        }

}

 

 

 

 

 

 

原创粉丝点击