/// <summary>
        /// Applies the properties to the specified cell definition.
        /// </summary>
        /// <param name="cd">The cell definition.</param>
        /// <param name="d">The cell descriptor.</param>
        protected virtual void ApplyProperties(CellDefinition cd, CellDescriptor d)
        {
            var pd = d.PropertyDefinition;

            cd.HorizontalAlignment = pd.HorizontalAlignment;
            cd.IsReadOnly          = pd.IsReadOnly;
            cd.FormatString        = pd.FormatString;
            if (pd.Converter != null)
            {
                cd.Converter = pd.Converter;
            }

            cd.ConverterParameter = pd.ConverterParameter;
            cd.ConverterCulture   = pd.ConverterCulture;

            cd.IsEnabledBindingParameter = pd.IsEnabledByValue;
            cd.IsEnabledBindingPath      = pd.IsEnabledByProperty;
            cd.BackgroundBindingPath     = pd.BackgroundProperty;

            if (pd.Background != null)
            {
                cd.BackgroundBindingSource = pd.Background;
                cd.BackgroundBindingPath   = string.Empty;
            }
        }
 protected override void ApplyProperties(CellDefinition cd, DataGrid owner, CellRef cell, PropertyDefinition pd, object item)
 {
     base.ApplyProperties(cd, owner, cell, pd, item);
     cd.IsEnabledBindingSource = this.isItemEnabledSource;
     cd.IsEnabledBindingParameter = "yes";
     cd.IsEnabledBindingPath = owner.Operator.GetBindingPath(owner, cell);
 }
        /// <summary>
        /// Creates a binding.
        /// </summary>
        /// <param name="d">The cd.</param>
        /// <returns>
        /// A binding.
        /// </returns>
        protected Binding CreateBinding(CellDefinition d)
        {
            var bindingMode = d.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;
            var formatString = d.FormatString;
            if (formatString != null && !formatString.StartsWith("{"))
            {
                formatString = "{0:" + formatString + "}";
            }

            var binding = new Binding(d.BindingPath)
            {
                Mode = bindingMode,
                Converter = d.Converter,
                ConverterParameter = d.ConverterParameter,
                StringFormat = formatString,
                ValidatesOnDataErrors = true,
                ValidatesOnExceptions = true,
                NotifyOnSourceUpdated = true
            };
            if (d.ConverterCulture != null)
            {
                binding.ConverterCulture = d.ConverterCulture;
            }

            return binding;
        }
 /// <summary>
 /// Sets the IsEnabled binding.
 /// </summary>
 /// <param name="cd">The cell definition.</param>
 /// <param name="element">The element.</param>
 protected virtual void SetIsEnabledBinding(CellDefinition cd, FrameworkElement element)
 {
     if (cd.IsEnabledBindingPath != null)
     {
         element.SetIsEnabledBinding(cd.IsEnabledBindingPath, cd.IsEnabledBindingParameter, cd.IsEnabledBindingSource);
     }
 }
        /// <summary>
        /// Creates a binding.
        /// </summary>
        /// <param name="d">The cd.</param>
        /// <returns>
        /// A binding.
        /// </returns>
        protected Binding CreateBinding(CellDefinition d)
        {
            // two-way binding requires a path...
            var bindingMode = d.IsReadOnly || string.IsNullOrEmpty(d.BindingPath) ? BindingMode.OneWay : BindingMode.TwoWay;

            var formatString = d.FormatString;

            if (formatString != null && !formatString.StartsWith("{"))
            {
                formatString = "{0:" + formatString + "}";
            }

            var binding = new Binding(d.BindingPath)
            {
                Mode                  = bindingMode,
                Converter             = d.Converter,
                ConverterParameter    = d.ConverterParameter,
                StringFormat          = formatString,
                ValidatesOnDataErrors = true,
                ValidatesOnExceptions = true,
                NotifyOnSourceUpdated = true
            };

            if (d.ConverterCulture != null)
            {
                binding.ConverterCulture = d.ConverterCulture;
            }

            return(binding);
        }
        /// <summary>
        /// Creates a check box control with data binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// A CheckBox.
        /// </returns>
        protected virtual FrameworkElement CreateCheckBoxControl(CellDefinition d)
        {
            if (d.IsReadOnly)
            {
                var cm = new CheckMark
                {
                    VerticalAlignment   = VerticalAlignment.Center,
                    HorizontalAlignment = d.HorizontalAlignment,
                };
                cm.SetBinding(CheckMark.IsCheckedProperty, this.CreateBinding(d));
                this.SetBackgroundBinding(d, cm);
                return(cm);
            }

            var c = new CheckBox
            {
                VerticalAlignment   = VerticalAlignment.Center,
                HorizontalAlignment = d.HorizontalAlignment
            };

            c.SetBinding(ToggleButton.IsCheckedProperty, this.CreateBinding(d));
            this.SetIsEnabledBinding(d, c);
            this.SetBackgroundBinding(d, c);
            return(c);
        }
        /// <summary>
        /// Creates the one way binding.
        /// </summary>
        /// <param name="cd">The cell definition.</param>
        /// <returns>
        /// A binding.
        /// </returns>
        protected Binding CreateOneWayBinding(CellDefinition cd)
        {
            var b = this.CreateBinding(cd);

            b.Mode = BindingMode.OneWay;
            return(b);
        }
        /// <summary>
        /// Creates the display control.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>The display control.</returns>
        protected virtual FrameworkElement CreateDisplayControlOverride(CellDefinition d)
        {
            var scd = d as SelectorCellDefinition;

            if (scd != null)
            {
                return(this.CreateTextBlockControl(scd));
            }

            var cb = d as CheckCellDefinition;

            if (cb != null)
            {
                return(this.CreateCheckBoxControl(cb));
            }

            var co = d as ColorCellDefinition;

            if (co != null)
            {
                return(this.CreateColorPreviewControl(co));
            }

            var td = d as TemplateCellDefinition;

            if (td != null)
            {
                return(this.CreateTemplateControl(td, td.DisplayTemplate));
            }

            return(this.CreateTextBlockControl(d));
        }
        /// <summary>
        /// Sets the background binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <param name="container">The container.</param>
        protected virtual void SetBackgroundBinding(CellDefinition d, Border container)
        {
            if (d.BackgroundBindingPath == null)
            {
                return;
            }

            var binding = new Binding(d.BackgroundBindingPath)
            {
                Source = d.BackgroundBindingSource
            };

            container.SetBinding(Border.BackgroundProperty, binding);
        }
        /// <summary>
        /// Sets the background binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <param name="c">The control.</param>
        protected virtual void SetBackgroundBinding(CellDefinition d, Control c)
        {
            if (d.BackgroundBindingPath == null)
            {
                return;
            }

            var binding = new Binding(d.BackgroundBindingPath)
            {
                Source = d.BackgroundBindingSource
            };

            c.SetBinding(Control.BackgroundProperty, binding);
        }
        /// <summary>
        /// Creates a color picker control with data binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// A color picker.
        /// </returns>
        protected virtual FrameworkElement CreateColorPickerControl(CellDefinition d)
        {
            var c = new ColorPicker
            {
                VerticalAlignment   = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Stretch,
                Focusable           = false
            };

            c.SetBinding(ColorPicker.SelectedColorProperty, this.CreateBinding(d));
            this.SetIsEnabledBinding(d, c);
            this.SetBackgroundBinding(d, c);
            return(c);
        }
        /// <summary>
        /// Creates a text block control with data binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// A TextBlock.
        /// </returns>
        protected virtual FrameworkElement CreateTextBlockControl(CellDefinition d)
        {
            var c = new TextBlockEx
            {
                HorizontalAlignment = d.HorizontalAlignment,
                VerticalAlignment   = VerticalAlignment.Center,
                Padding             = new Thickness(4, 0, 4, 0)
            };

            c.SetBinding(TextBlock.TextProperty, this.CreateOneWayBinding(d));
            this.SetIsEnabledBinding(d, c);

            return(this.CreateContainer(d, c));
        }
        /// <summary>
        /// Creates the edit control with data binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// The control.
        /// </returns>
        public virtual FrameworkElement CreateEditControl(CellDefinition d)
        {
            if (d.IsReadOnly)
            {
                return(null);
            }

            var element = this.CreateEditControlOverride(d);

            if (element != null)
            {
                // The edit control should fill the cell
                element.VerticalAlignment   = VerticalAlignment.Stretch;
                element.HorizontalAlignment = HorizontalAlignment.Stretch;
            }

            return(element);
        }
        /// <summary>
        /// Creates a container with background binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <param name="c">The control to add to the container.</param>
        /// <returns>The container element.</returns>
        protected virtual FrameworkElement CreateContainer(CellDefinition d, FrameworkElement c)
        {
            if (d.BackgroundBindingPath == null)
            {
                return(c);
            }

            var container = new Border {
                Child = c
            };
            var binding = new Binding(d.BackgroundBindingPath)
            {
                Source = d.BackgroundBindingSource
            };

            container.SetBinding(Border.BackgroundProperty, binding);
            return(container);
        }
        /// <summary>
        /// Creates the edit control with data binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// The control.
        /// </returns>
        public virtual FrameworkElement CreateEditControl(CellDefinition d)
        {
            if (d.IsReadOnly)
            {
                return null;
            }

            var element = this.CreateEditControlOverride(d);

            if (element != null)
            {
                // The edit control should fill the cell
                element.VerticalAlignment = VerticalAlignment.Stretch;
                element.HorizontalAlignment = HorizontalAlignment.Stretch;
            }

            return element;
        }
        /// <summary>
        /// Applies the properties to the specified cell definition.
        /// </summary>
        /// <param name="cd">The cell definition.</param>
        /// <param name="d">The cell descriptor.</param>
        protected virtual void ApplyProperties(CellDefinition cd, CellDescriptor d)
        {
            var pd = d.PropertyDefinition;

            cd.HorizontalAlignment = pd.HorizontalAlignment;
            cd.IsReadOnly          = pd.IsReadOnly;
            cd.FormatString        = pd.FormatString;
            if (pd.Converter != null)
            {
                cd.Converter = pd.Converter;
            }

            if (cd.Converter == null)
            {
                IValueConverter converter = null;
                foreach (var type in this.valueConverters.Keys)
                {
                    if (d.PropertyType.IsAssignableFrom(type))
                    {
                        converter = this.valueConverters[type];
                    }
                }

                cd.Converter = converter;
            }

            cd.ConverterParameter = pd.ConverterParameter;
            cd.ConverterCulture   = pd.ConverterCulture;

            cd.IsEnabledBindingParameter = pd.IsEnabledByValue;
            cd.IsEnabledBindingPath      = pd.IsEnabledByProperty;
            cd.BackgroundBindingPath     = pd.BackgroundProperty;

            if (pd.Background != null)
            {
                cd.BackgroundBindingSource = pd.Background;
                cd.BackgroundBindingPath   = string.Empty;
            }
        }
        /// <summary>
        /// Creates the edit control.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// The control.
        /// </returns>
        protected virtual FrameworkElement CreateEditControlOverride(CellDefinition d)
        {
            var co = d as SelectorCellDefinition;

            if (co != null)
            {
                return(this.CreateComboBox(co));
            }

            var cb = d as CheckCellDefinition;

            if (cb != null)
            {
                return(null);
            }

            var col = d as ColorCellDefinition;

            if (col != null)
            {
                return(this.CreateColorPickerControl(col));
            }

            var td = d as TemplateCellDefinition;

            if (td != null)
            {
                return(this.CreateTemplateControl(td, td.EditTemplate ?? td.DisplayTemplate));
            }

            var te = d as TextCellDefinition;

            if (te != null)
            {
                return(this.CreateTextBox(te));
            }

            return(this.CreateDisplayControl(d));
        }
        /// <summary>
        /// Creates a text block control with data binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// A TextBlock.
        /// </returns>
        protected virtual FrameworkElement CreateTextBlockControl(CellDefinition d)
        {
            var c = new TextBlockEx
            {
                HorizontalAlignment = d.HorizontalAlignment,
                VerticalAlignment   = VerticalAlignment.Center,
                Padding             = new Thickness(4, 0, 4, 0)
            };

            var binding = this.CreateOneWayBinding(d);

            var scd = d as SelectorCellDefinition;

            if (!string.IsNullOrEmpty(scd?.DisplayMemberPath))
            {
                binding.Path.Path += "." + scd.DisplayMemberPath;
            }

            c.SetBinding(TextBlock.TextProperty, binding);
            this.SetIsEnabledBinding(d, c);

            return(this.CreateContainer(d, c));
        }
        /// <summary>
        /// Applies the properties to the specified cell definition.
        /// </summary>
        /// <param name="cd">The cell definition.</param>
        /// <param name="owner">The owner.</param>
        /// <param name="cell">The cell.</param>
        /// <param name="pd">The row/column definition.</param>
        /// <param name="item">The current value of the cell.</param>
        protected virtual void ApplyProperties(CellDefinition cd, DataGrid owner, CellRef cell, PropertyDefinition pd, object item)
        {
            cd.HorizontalAlignment = pd.HorizontalAlignment;
            cd.BindingPath = pd.PropertyName ?? owner.Operator.GetBindingPath(owner, cell);
            cd.IsReadOnly = pd.IsReadOnly;
            cd.FormatString = pd.FormatString;
            if (pd.Converter != null)
            {
                cd.Converter = pd.Converter;
            }

            cd.ConverterParameter = pd.ConverterParameter;
            cd.ConverterCulture = pd.ConverterCulture;

            cd.IsEnabledBindingParameter = pd.IsEnabledByValue;
            cd.IsEnabledBindingPath = pd.IsEnabledByProperty;
            cd.BackgroundBindingPath = pd.BackgroundProperty;

            if (pd.Background != null)
            {
                cd.BackgroundBindingSource = pd.Background;
                cd.BackgroundBindingPath = string.Empty;
            }
        }
 protected override void ApplyProperties(CellDefinition cd, DataGrid owner, CellRef cell, PropertyDefinition pd, object item)
 {
     base.ApplyProperties(cd, owner, cell, pd, item);
     cd.BackgroundBindingSource = this.backgroundSource;
     cd.BackgroundBindingPath = owner.Operator.GetBindingPath(owner, cell);
 }
        /// <summary>
        /// Creates the display control with data binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// The control.
        /// </returns>
        public FrameworkElement CreateDisplayControl(CellDefinition d)
        {
            var element = this.CreateDisplayControlOverride(d);

            return(element);
        }
 /// <summary>
 /// Sets the IsEnabled binding.
 /// </summary>
 /// <param name="cd">The cell definition.</param>
 /// <param name="element">The element.</param>
 protected virtual void SetIsEnabledBinding(CellDefinition cd, FrameworkElement element)
 {
     if (cd.IsEnabledBindingPath != null)
     {
         element.SetIsEnabledBinding(cd.IsEnabledBindingPath, cd.IsEnabledBindingParameter, cd.IsEnabledBindingSource);
     }
 }
 /// <summary>
 /// Sets the background binding.
 /// </summary>
 /// <param name="d">The cell definition.</param>
 /// <param name="panel">The panel.</param>
 protected virtual void SetBackgroundBinding(CellDefinition d, Panel panel)
 {
     if (d.BackgroundBindingPath != null)
     {
         var binding = new Binding(d.BackgroundBindingPath) { Source = d.BackgroundBindingSource };
         panel.SetBinding(Panel.BackgroundProperty, binding);
     }
 }
        /// <summary>
        /// Creates a text block control with data binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// A TextBlock.
        /// </returns>
        protected virtual FrameworkElement CreateTextBlockControl(CellDefinition d)
        {
            var c = new TextBlockEx
            {
                HorizontalAlignment = d.HorizontalAlignment,
                VerticalAlignment = VerticalAlignment.Center,
                Padding = new Thickness(4, 0, 4, 0)
            };

            c.SetBinding(TextBlock.TextProperty, this.CreateOneWayBinding(d));
            this.SetIsEnabledBinding(d, c);

            var grid = new Grid();
            grid.Children.Add(c);
            this.SetBackgroundBinding(d, grid);
            this.SetIsEnabledBinding(d, grid);
            return grid;
        }
 /// <summary>
 /// Creates the display control with data binding.
 /// </summary>
 /// <param name="d">The cell definition.</param>
 /// <returns>
 /// The control.
 /// </returns>
 public FrameworkElement CreateDisplayControl(CellDefinition d)
 {
     var element = this.CreateDisplayControlOverride(d);
     return element;
 }
 /// <summary>
 /// Creates the one way binding.
 /// </summary>
 /// <param name="cd">The cell definition.</param>
 /// <returns>
 /// A binding.
 /// </returns>
 protected Binding CreateOneWayBinding(CellDefinition cd)
 {
     var b = this.CreateBinding(cd);
     b.Mode = BindingMode.OneWay;
     return b;
 }
        /// <summary>
        /// Creates the edit control.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// The control.
        /// </returns>
        protected virtual FrameworkElement CreateEditControlOverride(CellDefinition d)
        {
            var co = d as SelectCellDefinition;
            if (co != null)
            {
                return this.CreateComboBox(co);
            }

            var cb = d as CheckCellDefinition;
            if (cb != null)
            {
                return null;
            }

            var col = d as ColorCellDefinition;
            if (col != null)
            {
                return this.CreateColorPickerControl(col);
            }

            var td = d as TemplateCellDefinition;
            if (td != null)
            {
                return this.CreateTemplateControl(td, td.EditTemplate ?? td.DisplayTemplate);
            }

            var te = d as TextCellDefinition;
            if (te != null)
            {
                return this.CreateTextBox(te);
            }

            return this.CreateDisplayControl(d);
        }
        /// <summary>
        /// Creates the display control.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>The display control.</returns>
        protected virtual FrameworkElement CreateDisplayControlOverride(CellDefinition d)
        {
            var cb = d as CheckCellDefinition;
            if (cb != null)
            {
                return this.CreateCheckBoxControl(cb);
            }

            var co = d as ColorCellDefinition;
            if (co != null)
            {
                return this.CreateColorPreviewControl(co);
            }

            var td = d as TemplateCellDefinition;
            if (td != null)
            {
                return this.CreateTemplateControl(td, td.DisplayTemplate);
            }

            return this.CreateTextBlockControl(d);
        }
 /// <summary>
 /// Creates a color picker control with data binding.
 /// </summary>
 /// <param name="d">The cell definition.</param>
 /// <returns>
 /// A color picker.
 /// </returns>
 protected virtual FrameworkElement CreateColorPickerControl(CellDefinition d)
 {
     var c = new ColorPicker
     {
         VerticalAlignment = VerticalAlignment.Center,
         HorizontalAlignment = HorizontalAlignment.Stretch,
         Focusable = false
     };
     c.SetBinding(ColorPicker.SelectedColorProperty, this.CreateBinding(d));
     this.SetIsEnabledBinding(d, c);
     this.SetBackgroundBinding(d, c);
     return c;
 }
        /// <summary>
        /// Creates a check box control with data binding.
        /// </summary>
        /// <param name="d">The cell definition.</param>
        /// <returns>
        /// A CheckBox.
        /// </returns>
        protected virtual FrameworkElement CreateCheckBoxControl(CellDefinition d)
        {
            if (d.IsReadOnly)
            {
                var cm = new CheckMark
                {
                    VerticalAlignment = VerticalAlignment.Center,
                    HorizontalAlignment = d.HorizontalAlignment,
                };
                cm.SetBinding(CheckMark.IsCheckedProperty, this.CreateBinding(d));
                this.SetBackgroundBinding(d, cm);
                return cm;
            }

            var c = new CheckBox
            {
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = d.HorizontalAlignment
            };
            c.SetBinding(ToggleButton.IsCheckedProperty, this.CreateBinding(d));
            this.SetIsEnabledBinding(d, c);
            this.SetBackgroundBinding(d, c);
            return c;
        }