Я работаю с классом DesignSurface, и у меня возникла разочаровывающая проблема, которую я не могу понять. Я перетаскиваю элементы из своей панели инструментов и без проблем удаляю их в свою форму, но я хочу изменить свойства этих элементов, поскольку они помещаются на DesignSurface. Так, например, если я перетаскиваю ярлык на DesignSurface, я могу изменить значение BackColor элемента управления. Я знаю, что ToolboxItem предоставляет CreateComponents(), который принимает необязательный параметр свойств, но он вызывается API нижнего уровня, и я не вижу, где и как его переопределить, поэтому я могу предоставить свои собственные значения. У кого-нибудь есть идеи? Благодаря!Modify ToolboxItem во время перетаскивания
ответ
Хотя я чувствую, что это немного «взломанный», я не обязательно знаю, что это неправильно (и если это технически «неправильно», пожалуйста, оставьте мне отзыв о лучших практиках!), И он решил проблему на рука.
Что я в итоге сделал, это расширение ToolboxItem на основе прочитанной мной статьи MSDN.
public class SurfaceToolboxItem : ToolboxItem
{
private delegate void SetTextHandler(Control c, string text);
public string ReportFieldName { get; set; }
protected override IComponent[] CreateComponentsCore(IDesignerHost host)
{
var ctrl = (Label)host.CreateComponent(typeof(Label));
var root = (Control) host.RootComponent;
root.BeginInvoke(new SetTextHandler(SetText),
new object[] {ctrl, ReportFieldName});
return new IComponent[]{ ctrl };
}
private void SetText(Control ctrl, string text)
{
ctrl.Text = text;
}
}
Некоторые очевидные недостатки:
- Этот пункт будет только когда-либо создать контроль этикетки
- Этот пункт будет только когда-либо установить свойство текста указанного управления этикетки на основе струнной собственности общественности.
Чтобы преодолеть эти проблемы, пункт может быть расширен, чтобы действовать как базовый ToolboxItem (реализующие CTOR принимающих параметр типа, что позволяет словарь имен собственности/ценностей, передаваемых в быть установлены после того, как тот факт, и т. д.)
Кроме того, это сломало функциональность перетаскивания с панели инструментов на поверхность дизайна, и это было особенно неприятно, потому что это было не слишком очевидно. Проблема была в моем методе DeserializeToolboxItem моей реализации Toolbox Service.
Первоначально это выглядело так:
ToolboxItem IToolboxService.DeserializeToolboxItem(object serializedObject)
{
return (ToolboxItem) ((DataObject) serializedObject).GetData(typeof (ToolboxItem));
}
Проблема заключалась в том, что приведение к ToolboxItem возвращается нуль, так как объект был типа SurfaceToolboxItem поэтому я изменил способ выглядеть следующим образом:
ToolboxItem IToolboxService.DeserializeToolboxItem(object serializedObject)
{
var data = (ToolboxItem) ((DataObject) serializedObject).GetData(typeof (ToolboxItem));
return data ?? (ToolboxItem)((DataObject)serializedObject).GetData(typeof(SurfaceToolboxItem));
}
Таким образом, поддерживается как мое расширение, так и по умолчанию ToolboxItem.
Это не ответ, я просто хочу показать, что я нашел с вашей проблемой. Я думаю, у вас должен быть собственный способ доступа к вашему собственному Toolbox
, и этот Toolbox
реализует интерфейс IToolboxService
, этот интерфейс имеет метод под названием GetSelectedToolboxItem(IDesignerHost)
. И я думаю, что вы должны реализовать этот метод, чтобы указать, как вы получаете выбранный элемент, я думаю, что ваш Toolbox
должен иметь некоторый элемент управления, который содержит список элементов панели инструментов, это может быть ListBox
...
Вторая важная вещь это IDesignerHost
, так как я понимаю, это может быть то, что вас интересует. Оно должно иметь какое-то отношение к вашему DesignSurface
. Он имеет некоторые события для вас заинтересовать, как это:
IDesignerHost host = {some method to get it};
host.TransactionClosed += (s,e) => {
ICollection selected = ((ISelectionService)host.GetService(typeof(ISelectionService))).GetSelectedComponents();
IComponent[] comps = new IComponent[selected.Count];
selected.CopyTo(comps, 0);
string displayName = YourToolBox.GetSelectedToolboxItem(host).DisplayName;
((Control)comps[0]).Text = displayName;
};
Я протестированные в проекте, который реализует очень сложный IDesignerHost
, он имеет метод для меня, чтобы создать host
для тестирования. При перетаскивании элемента управления на DesignSurface
код по-прежнему не влияет на код TransactionClosed
, я должен сделать что-то вроде Resizing, Moving...
, и после этого возникает событие TransactionClosed
и оно показывает DisplayName
OK. Я не нахожу другого события лучше, самым подходящим событием должно быть ComponentAdded
или ComponentAdding
, но ни один из них не работает.
У меня есть еще один вопрос, образец проекта, который я пробовал, - это CustomFormsDesigner
, который работает как другое обычное приложение Windows Forms, оно показывает панель инструментов, конструкцию и сетку свойств. Я делаю все после запуска. Но как насчет вашего дела? Я имею в виду, когда вы перетаскиваете свой элемент управления на свой DesignSurface, вы все еще находите время разработки в окне Visual Studio? или в вашем собственном приложении (как Designer)?
Должен сказать, что эта проблема настолько сложна для меня. Благодаря вам, я знаю об этом виде приложения.
Эй, король короля. Несколько вещей. Я должен был быть более ясным: я на самом деле использую System.ComponentModel.Design.DesignSurface, поэтому большая часть работы с дизайнерами отвлекается от меня. Мой RootComponent имеет тип UserControl и ваш код работает, он запускается каждый раз, когда элемент управления добавляется к нему, но моя более конкретная проблема заключается в следующем: все «Инструменты» в моем ящике инструментов имеют тип Label, а их DisplayName установлен в имя поля в наборе данных отчета. Мне нужно значение DisplayName, чтобы я знал, в каком поле привязать элемент управления. Но я открыт для предложения – dparsons
@abszero Я нашел проблему с моим решением, она работает только тогда, когда я перетаскиваю элемент управления из другого контейнера в форме на него, если перетаскивать новый из панели инструментов, это не Работа. Почему это работает для вас? Похоже, у вас есть свой собственный набор инструментов со своими «инструментами»? –
У меня есть класс, который реализует IToolboxService, и у меня есть ListBox, который содержит несколько элементов ToolboxItem, которые замужем за этим классом. Затем я добавляю эту службу в свой DesignSurface. – dparsons
- 1. Перерисовывание во время перетаскивания
- 2. ctypes.Structure Modify _fields_ во время выполнения
- 3. Ручка KeyDown во время перетаскивания
- 4. Сделать управление прозрачным для перетаскивания событий во время перетаскивания
- 5. Картина TPaintBox во время перетаскивания с DragImage
- 6. Выделите компонент во время перетаскивания пользователя
- 7. Нет ключевых событий во время перетаскивания HTML5
- 8. Скрыть/настроить курсор во время перетаскивания HTML5
- 9. Пользовательский курсор во время основного перетаскивания
- 10. Triggering Mousemove во время перетаскивания (HTML5)
- 11. Изменение jQuery draggable helper во время перетаскивания
- 12. Автоматическая прокрутка Droppable DIV во время перетаскивания
- 13. Как настроить изображение, отображаемое во время перетаскивания?
- 14. Получить направление вращения во время перетаскивания - GSAP
- 15. Рендеринг Перетаскиваемый объект во время перетаскивания
- 16. Получить положение мыши во время перетаскивания
- 17. Как показывать значки во время перетаскивания
- 18. Открытие пробела в NSTableView во время перетаскивания
- 19. Как сделать AutoScroll DataGridView во время перетаскивания
- 20. Как выполнить код во время операции перетаскивания?
- 21. Укладка объекта во время его перетаскивания
- 22. Флаг MK_CONTROL, очищенный во время операции перетаскивания
- 23. Как предотвратить нажатие элементов во время перетаскивания?
- 24. MonitorFromWindow (DefaultToNearest) не работает во время перетаскивания
- 25. JXTable + GlazedLists + обновление во время перетаскивания = проблема
- 26. Элементы прокрутки во время перетаскивания объекта
- 27. меню закрывается во время перетаскивания с NSStatusItem
- 28. Отключить миниатюрное во время перетаскивания на JQuery
- 29. Как обрабатывать листья мыши во время перетаскивания
- 30. Drag во время перетаскивания над сеткой
Вы имеете в виду, что на вашем 'DesignSurface' есть некоторые элементы, и вы хотите изменить некоторые свойства этих элементов во время разработки (через окно« Свойства »)? Как выглядит ваш 'DesignSurface'? Это что-то вроде «Панели»? Ваш вопрос не достаточно ясен для меня. –
DesignSurface - это UserControl. То, что я на самом деле пытаюсь сделать, это то, что когда пользователь бросает элемент управления в UserControl, я хочу изменить некоторые свойства этого элемента управления, прежде чем он будет фактически отображаться на поверхности. Конечно, если бы я хотел изменить значения элемента управления после того, как они были на DesignSurface, я просто настрою PropertyGrid. – dparsons
Это немного странно для меня? Почему вы должны это делать? –