У меня есть приложение, которое использует Windows.Form вместе с Infragistics для GUI / UI. Я хотел отделить распределение свойств, таких как BackColor, ForeColor и т. Д., От моего основного проекта, чтобы сделать его более приятным для чтения и меньшим. Поэтому я создал новый проект в VS (2017, Professional), в котором я установил все свойства, используя отражение, потому что я хотел избежать ссылки на мой основной проект в моем проекте с графическим интерфейсом.
Я получаю элементы управления, которые хочу изменить следующим образом:
object controlsCollectionObject = currentObject.GetType().GetProperty("Controls").GetValue(currentObject);
ArrayList controlsInnerList = controlsCollectionObject.GetType().GetProperty("InnerList", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(controlsCollectionObject) as ArrayList;
Этот InnerList содержит элементы управления этого объекта ControlCollection.
Затем я повторяю этот список и ищу два свойства, которые я хочу установить:
Type listItemType = listItem.GetType();
if (wantedControls.Contains(listItem.GetType().Name))
{
listItemName.Append(listItemType.GetProperty("Name").GetValue(listItem) as string);
if (!controlElements.ContainsKey(listItemName.ToString()))
{
controlElements.Add(listItemName.ToString(), new Tuple<object, PropertyInfo>(listItem, listItemType.GetProperty("BackColor")));
}
if (listItemType.GetProperty("Appearance") != null)
{
appearanceObject = listItemType.GetProperty("Appearance").GetValue(listItem);
listItemName.Append("_Appearance");
controlElements.Add(listItemName.ToString(), new Tuple<object, PropertyInfo>(appearanceObject, appearanceObject.GetType().GetProperty("BackColor")));
}
if (!doNotPushInStack.Contains(listItem.GetType().Name))
{
objectsToIterate.Push(listItem);
}
listItemName.Clear();
}
Где controlElements
- это Dictionary<string, Tuple<object, PropertyInfo>>
, а wantedControls
- строковый массив, содержащий все типы объектов управления, которые я хочу найти и изменить.
objectsToIterate
- это Stack<object>
, который я использовал, чтобы избежать рекурсии, и потому что я хотел также найти определенные элементы управления, чтобы проверить, содержат ли они другие элементы управления, я мог бы захотеть изменить.
Впоследствии я установил свойства следующим образом:
private static void SetControlProperties()
{
Tuple<object,PropertyInfo> objectReferenceAndBackColor;
DataRow dbPanels;
for (int i = 0; i < panelsData.Length; i++)
{
dbPanels = panelsData[i];
if(controlElements.TryGetValue(dbPanels["ButtonText"].ToString(), out objectReferenceAndBackColor))
{
objectReferenceAndBackColor.Item2.SetValue(objectReferenceAndBackColor.Item1, Color.FromName(dbPanels["BackColor1"].ToString()));
Debug.WriteLine(objectReferenceAndBackColor.Item2.GetValue(objectReferenceAndBackColor.Item1).ToString() + " I am Object of: " + objectReferenceAndBackColor.Item1.ToString());
}
}
}
panelsData
- это DataRow
, который содержит все мои значения, которые я хочу записать в свойствах. Все значения сохраняются в локальной базе данных SQL.
Причина, по которой я проверяю ["ButtonText"]
, заключается в том, что я временно записал наборы данных для элементов управления в свой набор данных «Button»
Для большинства компонентов, таких как панели, он работает нормально, но некоторые компоненты инфраструктуры, такие как UltraTextEditor, не работают. Кажется, он не регистрирует и не принимает изменения, которые я установил с помощью SetValue (), из отражений.
После завершения, когда я проверяю в своем основном проекте, установлены ли значения, я вижу, что некоторые компоненты не сохраняют эти значения:
Color [Transparent] I am Object of: Infragistics.Win.UltraWinEditors.UltraTextEditor
Вместо этого в журнале должно выглядеть так:
Color [255; 11; 110; 143] I am Object of: Infragistics.Win.UltraWinGrid.UltraGrid
Значения, которые я пытаюсь установить, не только для чтения. UltraTextEditor.UseAppStyling
имеет значение false, а также свойство UseOsThemes
. Я также проверил, перезаписываются ли мои значения в какой-то момент, но это не так. Я использовал тот же подход, который я показал здесь, в моем основном проекте, чтобы увидеть, была ли это проблема с разрешениями, но это тоже не сработало.
Я могу установить задний цвет этих компонентов внутри моего основного проекта, просто используя ultryTextEditorTest.BackColor = Color.Blue;
, но через отражение он не записывает его в свойство. Я проверил значения из своей базы данных и SQL-запроса в моем коде, чтобы увидеть, если я сделал ошибку, но все правильно, так что сейчас я не уверен, в чем проблема или, по крайней мере, почему это не позволяет мне установить backcolor через отражение.
Я знаю, что мог бы просто установить цвета в обычном режиме, но в этот момент я упрям и хочу знать, почему это не работает или может быть невозможно сделать это таким образом, потому что инфраструктура запрещает мне это делать. То есть, если проблема связана с инфра-сетью или я допустил ошибку в своем коде, которую я не вижу.
Надеюсь, что это не так много сразу, если оно даст мне знать, и я постараюсь разбить его чуть поподробнее, чтобы его было легче читать и понимать.
Спасибо за вашу помощь заранее.