Posted 9 March 2022, 5:31 am EST
Nitin, thank you very much for that advice. It works great.
However, I am experiencing an issue with the custom Property Editors. When a new C1PropertyGrid.SelectedObject is set, I get the following exception:
System.ArgumentException: ‘Must disconnect specified child from current parent Visual before attaching to new parent Visual.’
I’m assuming that it has something to do with the Detach() method of the custom editor, which currently does nothing. I know it is related to the custom property editors because, if I remove them from the C1PropertyGrid.AvailableEditors list, I don’t get the exception.
Here is the code for one of my custom editors:
using C1.WPF.PropertyGrid;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace Views.PropertyGridEditors
{
/// <summary>
/// C1PropertyGrid List Property Editor
/// </summary>
public class SequenceCategoryEditor : Grid, ITypeEditorControl
{
public event PropertyChangedEventHandler ValueChanged;
/// <summary>
/// The Sequence categories collection
/// </summary>
private CmiAction Action { get; set; }
public void Attach(PropertyAttribute property)
{
if (Supports(property))
{
Action = property.SelectedObject as CmiAction;
// Add the controls to this StackPanel
CreateControls(Action.Categories.GetList(), out TextBox textBox, out Button button);
}
}
/// <summary>
/// Add the controls that will show in the C1PropertyGrid PropertyBox
/// </summary>
/// <param name="categories"></param>
private void CreateControls(ObservableCollection<string> categories, out TextBox text, out Button button)
{
// Create the columns
ColumnDefinition textColumn = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };
ColumnDefinition buttonColumn = new ColumnDefinition() { Width = GridLength.Auto };
ColumnDefinitions.Add(textColumn);
ColumnDefinitions.Add(buttonColumn);
// Add the TextBox
text = new TextBox() { Margin = new Thickness(0, 0, 3, 0), Style = FindResource(typeof(TextBox)) as Style, HorizontalAlignment = HorizontalAlignment.Stretch };
text.TextChanged += Text_TextChanged;
Children.Add(text);
UpdateEditorText(categories);
// Add the Button
button = new Button() { Margin = new Thickness(0), Style = FindResource(typeof(Button)) as Style };
button.Content = "...";
button.Width = 30;
button.FontSize = 14;
button.FontWeight = FontWeights.Bold;
button.Click += Button_Click;
Children.Add(button);
// Set column for the controls
text.SetValue(Grid.ColumnProperty, 0);
button.SetValue(Grid.ColumnProperty, 1);
}
/// <summary>
/// Show the SequenceCategoriesEditWindow
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Click(object sender, RoutedEventArgs e)
{
SequenceCategoriesEditWindow editor = new SequenceCategoriesEditWindow(Action.Categories.GetList());
// If user presses OK button, update the Action categories
if (editor.ShowDialog() == true)
{
Action.Categories.SetList(editor.SequenceCategoriesView.TextItems);
UpdateEditorText(Action.Categories.GetList());
}
}
/// <summary>
/// Update the comma separated list of strings in the TextBox child
/// </summary>
/// <param name="categories"></param>
private void UpdateEditorText(ObservableCollection<string> categories)
{
StringBuilder sb = new StringBuilder();
if (categories.Count > 0)
{
sb.Append(categories[0]);
}
for (int i = 1; i < categories.Count; i++)
{
sb.AppendFormat(", {0}", categories[i]);
}
(Children[0] as TextBox).Text = sb.ToString();
(Children[0] as TextBox).ToolTip = sb.ToString();
}
/// <summary>
/// Don't allow changes in the textBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Text_TextChanged(object sender, TextChangedEventArgs e)
{
e.Handled = true;
}
public ITypeEditorControl Create()
{
return this;
}
public void Detach(PropertyAttribute property)
{
// Do nothing?
}
public bool Supports(PropertyAttribute Property)
{
return Property.PropertyInfo.PropertyType == typeof(CmiSequenceCategoryList);
}
}
}
Is there not somebody at GrapeCity that lives in the US so that I don’t have to wait a day for responses? Just wondering. As you can imagine, it results in huge delays for the software release.