301 lines
11 KiB
C#
301 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Text;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.Design;
|
|
using System.Windows.Forms;
|
|
using System.Reflection;
|
|
|
|
namespace Volian.Base.Library
|
|
{
|
|
// The PropGridCollEditor expands the functionality of the CollectionEditor (the collection editor comes up when in a
|
|
// property grid, and the current selected item is a collection, and the user selects the '...'.
|
|
public class PropGridCollEditor : CollectionEditor
|
|
{
|
|
// Define a static event to expose the inner PropertyGrid's
|
|
// PropertyValueChanged event args...
|
|
public delegate void MyPropertyValueChangedEventHandler(object sender, PropertyValueChangedEventArgs e);
|
|
public static event MyPropertyValueChangedEventHandler MyPropertyValueChanged;
|
|
private bool AllowAddDel = false; // flags whether the Add/Delete buttons should be displayed:
|
|
// Inherit the default constructor from the standard
|
|
// Collection Editor...
|
|
private Type _origType;
|
|
public PropGridCollEditor(Type type)
|
|
: base(type)
|
|
{
|
|
AllowAddDel = false;
|
|
_origType = type;
|
|
if (type.Name == "ReplaceStrData") AllowAddDel = true; // Defaults to not having the 'Add' & 'Remove' buttons.
|
|
}
|
|
|
|
protected override Type CreateCollectionItemType()
|
|
{
|
|
return base.CreateCollectionItemType();
|
|
}
|
|
private Button resetbtn = null;
|
|
// Override this method in order to access the containing user controls
|
|
// from the default Collection Editor form or to add new ones...
|
|
protected override CollectionForm CreateCollectionForm()
|
|
{
|
|
// Getting the default layout of the Collection Editor...
|
|
CollectionForm collectionForm = base.CreateCollectionForm();
|
|
|
|
Form frmCollectionEditorForm = collectionForm as Form;
|
|
|
|
// The Add/Remove buttons are made invisible:
|
|
if (!AllowAddDel) HideAddRemoveButtons(0, frmCollectionEditorForm);
|
|
Button okbtn = FindOkButton(frmCollectionEditorForm);
|
|
|
|
if (!AllowAddDel)
|
|
{
|
|
// add a reset button and put next to ok button:
|
|
resetbtn = new Button();
|
|
resetbtn.Text = "Reset";
|
|
resetbtn.Location = new System.Drawing.Point(okbtn.Location.X - 20, okbtn.Location.Y);
|
|
resetbtn.Width = 250;
|
|
resetbtn.Visible = true;
|
|
resetbtn.Enabled = false; // only enabled on data change
|
|
resetbtn.Click += resetbtn_Click;
|
|
okbtn.Parent.Controls.Add(resetbtn);
|
|
}
|
|
SetMembersLabel(collectionForm);
|
|
TableLayoutPanel tlpLayout = frmCollectionEditorForm.Controls[0] as TableLayoutPanel;
|
|
if (tlpLayout != null)
|
|
{
|
|
// Get a reference to the inner PropertyGrid and hook an event handler to it.
|
|
if (tlpLayout.Controls[5] is PropertyGrid)
|
|
{
|
|
propertyGrid = tlpLayout.Controls[5] as PropertyGrid;
|
|
propertyGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(propertyGrid_PropertyValueChanged);
|
|
propertyGrid.SelectedGridItemChanged += PG_SelectedGridItemChanged;
|
|
}
|
|
}
|
|
|
|
return collectionForm;
|
|
}
|
|
|
|
// when the reset button is clicked the data will be reset to the data from the original format file. Note that if
|
|
// data is added to the UCF that is part of a collection, code will need to be added here to reset the value.
|
|
void resetbtn_Click(object sender, EventArgs e)
|
|
{
|
|
resetbtn.Text = "Reset";
|
|
resetbtn.Enabled = false;
|
|
if (SelectedGridField.Contains("Left Margin"))
|
|
ResetValue(propertyGrid.SelectedGridItem.Parent.Value, "LeftMargin");
|
|
else if (SelectedGridField.Contains("Page Length"))
|
|
ResetValue(propertyGrid.SelectedGridItem.Parent.Value, "PageLength");
|
|
else if (SelectedGridField.Contains("WindowsFont"))
|
|
ResetValue(propertyGrid.SelectedGridItem.Parent.Value, "WindowsFont");
|
|
else if (SelectedGridField.Contains("Inactive CheckOff Header"))
|
|
ResetValue(propertyGrid.SelectedGridItem.Parent.Value, "Inactive");
|
|
else if (SelectedGridField.Contains("Inactive CheckOff"))
|
|
ResetValue(propertyGrid.SelectedGridItem.Parent.Parent.Value, "Inactive");
|
|
}
|
|
private void ShowReflection(Object data)
|
|
{
|
|
if (data == null) return;
|
|
//Object data = new A();
|
|
FieldInfo[] fields = data.GetType().GetFields(BindingFlags.Public |
|
|
BindingFlags.NonPublic |
|
|
BindingFlags.Instance);
|
|
String str = "";
|
|
foreach (FieldInfo f in fields)
|
|
{
|
|
str += f.Name + " = " + f.GetValue(data) + "\r\n";
|
|
}
|
|
Console.WriteLine("reflection = {0}", str);
|
|
}
|
|
PropertyGrid propertyGrid = null;
|
|
private string SelectedGridField = "";
|
|
// The following method is used to enable and set text on the 'Reset' button. When a grid item is selected, if it has
|
|
// UCF data, then put the original value as part of the button text & enable it:
|
|
void PG_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
|
|
{
|
|
if (resetbtn == null) return;
|
|
if (propertyGrid != null) Console.WriteLine(LabelPath(propertyGrid.SelectedGridItem)); // PG.SelectedGridItem.Label + " : " + PG.SelectedGridItem.Value;
|
|
// see if data has changed, and if so, enable the Reset button.
|
|
bool enabled = false;
|
|
resetbtn.Text = "Reset";
|
|
SelectedGridField = LabelPath(propertyGrid.SelectedGridItem);
|
|
if (SelectedGridField.Contains("WindowsFont"))
|
|
{
|
|
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Value, "WindowsFont");
|
|
if (origForButton != null)
|
|
{
|
|
resetbtn.Text = "Reset to " + origForButton;
|
|
enabled = true;
|
|
}
|
|
}
|
|
else if (SelectedGridField.Contains("Left Margin"))
|
|
{
|
|
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Value, "LeftMargin");
|
|
if (origForButton != null)
|
|
{
|
|
resetbtn.Text = "Reset to " + origForButton;
|
|
enabled = true;
|
|
}
|
|
}
|
|
else if (SelectedGridField.Contains("Page Length"))
|
|
{
|
|
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Value, "PageLength");
|
|
if (origForButton != null)
|
|
{
|
|
resetbtn.Text = "Reset to " + origForButton;
|
|
enabled = true;
|
|
}
|
|
}
|
|
else if (SelectedGridField.Contains("Active CheckOff Header"))
|
|
{
|
|
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Parent.Value, "Active");
|
|
if (origForButton != null)
|
|
{
|
|
resetbtn.Text = "Reset to " + origForButton;
|
|
enabled = true;
|
|
}
|
|
}
|
|
else if (SelectedGridField.Contains("Active CheckOff"))
|
|
{
|
|
string origForButton = OrigValue(propertyGrid.SelectedGridItem.Parent.Parent.Value, "Active");
|
|
if (origForButton != null)
|
|
{
|
|
resetbtn.Text = "Reset to " + origForButton;
|
|
enabled = true;
|
|
}
|
|
}
|
|
else enabled = false;
|
|
|
|
resetbtn.Enabled = enabled;
|
|
}
|
|
// This code,using data reflection, will determine the if there is UCF (changed) data, and if so
|
|
// will return its value as a string for concatenation of Reset button text.
|
|
private string OrigValue(object data, string fieldName)
|
|
{
|
|
FieldInfo fldVal = null;
|
|
FieldInfo fldOrig = null;
|
|
if (data == null) return null;
|
|
FieldInfo[] fields = data.GetType().GetFields(BindingFlags.Public |
|
|
BindingFlags.NonPublic |
|
|
BindingFlags.Instance);
|
|
// Go through the fields in the data structure, looking to match that passed in. Also look for the original
|
|
// field to compare the 2 to see if a change was made, i.e. UCF data exists.
|
|
foreach (FieldInfo f in fields)
|
|
{
|
|
if (f.Name == "_" + fieldName) fldVal = f;
|
|
if (f.Name == "_Orig" + fieldName) fldOrig = f;
|
|
}
|
|
if (fldVal != null && fldOrig != null)
|
|
{
|
|
try
|
|
{
|
|
// see if values are different:
|
|
string orig = fldOrig.GetValue(data).ToString();
|
|
string newv = fldVal.GetValue(data).ToString();
|
|
string retval = fldOrig.GetValue(data).ToString();
|
|
if (retval.StartsWith("[Font:"))
|
|
{
|
|
retval = retval.Replace("[Font: Name=", "").Replace(", Size=", ",");
|
|
}
|
|
if (orig != newv) return retval;
|
|
else return null;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
// The following Resets the format variable's value from the original format (as stored in the 'OrigXXX' field in FormatConfig
|
|
private void ResetValue(object data, string fieldName)
|
|
{
|
|
FieldInfo fldVal = null;
|
|
FieldInfo fldOrig = null;
|
|
if (data == null) return;
|
|
FieldInfo[] fields = data.GetType().GetFields(BindingFlags.Public |
|
|
BindingFlags.NonPublic |
|
|
BindingFlags.Instance);
|
|
foreach (FieldInfo f in fields)
|
|
{
|
|
if (f.Name == "_" + fieldName) fldVal = f;
|
|
if (f.Name == "_Orig" + fieldName) fldOrig = f;
|
|
}
|
|
if (fldVal != null && fldOrig != null)
|
|
{
|
|
fldVal.SetValue(data, fldOrig.GetValue(data));
|
|
propertyGrid.Refresh();
|
|
}
|
|
}
|
|
// Remove this on release, and any uses of it.
|
|
private string LabelPath(GridItem gi)
|
|
{
|
|
return (gi.Parent == null ? "" : LabelPath(gi.Parent) + ":" + gi.Label);
|
|
}
|
|
|
|
// set the 'members' label to better reflect what is displayed:
|
|
private bool SetMembersLabel(Control myControl)
|
|
{
|
|
if (myControl is Label && myControl.Text.ToUpper().Contains("MEMBER"))
|
|
{
|
|
string dt = myControl.TopLevelControl.Text;
|
|
if (dt.ToUpper().Contains("DOCSTYL")) myControl.Text = "Section Types";
|
|
else if (dt.ToUpper().Contains("REPLACE")) myControl.Text = "Replace Words";
|
|
else if (dt.ToUpper().Contains("CHECKOFFHEADER")) myControl.Text = "CheckOff Headers";
|
|
else if (dt.ToUpper().Contains("CHECKOFF")) myControl.Text = "CheckOffs";
|
|
else if (dt.ToUpper().Contains("STEP")) myControl.Text = "Steps";
|
|
return true;
|
|
}
|
|
if (myControl.Controls != null && myControl.Controls.Count > 0)
|
|
{
|
|
foreach (Control con in myControl.Controls)
|
|
{
|
|
bool found = SetMembersLabel(con);
|
|
if (found == true) return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
// This code looks for the 'OK' button, so that the 'Reset' button can be placed by it.
|
|
private Button FindOkButton(Control myControl)
|
|
{
|
|
if (myControl is Button && myControl.Text == "OK")
|
|
{
|
|
return myControl as Button;
|
|
}
|
|
if (myControl.Controls != null && myControl.Controls.Count > 0)
|
|
{
|
|
foreach (Control con in myControl.Controls)
|
|
{
|
|
Button found = FindOkButton(con);
|
|
if (found != null) return found;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Find the 'Add' & 'Remove' buttons based on their text, and then make invisible.
|
|
private void HideAddRemoveButtons(int level, Control myControl)
|
|
{
|
|
if (myControl.Text == "&Add" || myControl.Text == "&Remove")
|
|
{
|
|
myControl.Visible = false;
|
|
return;
|
|
}
|
|
if (myControl.Controls != null && myControl.Controls.Count > 0)
|
|
{
|
|
foreach (Control con in myControl.Controls)
|
|
HideAddRemoveButtons(level + 1, con);
|
|
}
|
|
}
|
|
|
|
void propertyGrid_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
|
|
{
|
|
// Fire our customized collection event...
|
|
if (PropGridCollEditor.MyPropertyValueChanged != null)
|
|
{
|
|
PropGridCollEditor.MyPropertyValueChanged(this, e);
|
|
}
|
|
}
|
|
}
|
|
}
|