С# показывает просматриваемые дочерние свойства в дизайнере

Я использую .NET C# со стандартными WinForms, а не WPF.

у меня такая ситуация. Я создаю пользовательский элемент управления для месячного календаря, похожий на .NET, но с немного большей функциональностью. У меня есть форма пользовательского управления, которая заполняется объектами кнопок, представляющими даты. Кнопки могут быть окрашены в разные цвета в зависимости от их состояния (выбраны, наведены курсором мыши, выходные...)

То, как я хотел бы, чтобы это работало, - это расширение класса кнопок для принятия состояний, которые определяют цвета, а не окрашивание их из родительского (пользовательского элемента управления) класса. На данный момент существует 10 цветов, и мне бы очень не хотелось засорять код пользовательского управления условиями окраски.

Также я хотел бы выбрать все цвета во время разработки, используя просматриваемые свойства дизайнера. Проблема в том, что дизайнер показывает только свойства, определенные в классе пользовательского элемента управления, а не его дочерние элементы (кнопки).

Есть ли обходной путь для этой проблемы? Короче говоря, я хочу изменить цвета, используя внутренние свойства кнопки, и иметь возможность выбирать их во время разработки, используя свойства дизайнера, а не жестко кодировать их вручную.


person Zoran Ivancevic    schedule 13.11.2009    source источник
comment
Некоторые примеры кода того, как выглядят ваши дочерние классы, помогут   -  person thecoop    schedule 13.11.2009
comment
Дочерний элемент — это простой класс, который расширяет класс Button. Он имеет различные конструкторы в зависимости от размера, текста и местоположения. Я хотел бы, чтобы все цвета были свойствами этого класса. Но я хотел бы выбрать их из окна свойств дизайнера пользовательского элемента управления (родительского), когда я перетаскиваю пользовательский элемент управления в кадр.   -  person Zoran Ivancevic    schedule 13.11.2009
comment
Добавлен пример; это миллион миль?   -  person Marc Gravell    schedule 13.11.2009


Ответы (4)


Хорошо, я попытаюсь объяснить через код:

Например, у меня есть пользовательский элемент управления и класс кнопок. Я хочу открыть свойства Button и сделать их видимыми среди свойств MyControl в конструкторе.

class MyControl : UserControl
{
     private MyButton button;
     button.ChangeStyle("Selected");
}

class MyButton : Button
{
     private Color buttonColor;

     public void ChangeStyle(string styleName)
     {
          if (styleName == "Selected")
              this.BackColor = buttonColor;
     }

     [Browsable(true)]
     [Category("Button style")]
     public Color ButtonColor
     {
          get { return buttonColor; }
          set { buttonColor = value; }
     }
}

Это простой пример. Обычно у меня есть 5 разных стилей, включая цвет фона и переднего плана для каждого из них. Поэтому вместо управления цветами в классе MyControl я хотел бы определить их в классе MyButton. Но проблема в том, что свойства класса MyButton не видны в конструкторе, потому что он фокусируется только на свойствах MyControl.

Кстати. игнорировать отсутствующие конструкторы и другие базовые классы в примере кода

Я не могу использовать:

[Category("Wonder Control")]
public Color ButtonBackColor { get { return button.BackColor; } set { button.BackColor = value; }

потому что у меня есть 30 кнопок в MyControl (дни в месяце), и я не могу ссылаться только на один объект.

person Zoran Ivancevic    schedule 13.11.2009

Чтобы свойство было видно в дизайнере, оно должно быть общедоступным с геттером и сеттером — судя по тому, что вы говорите, свойства — это только геттеры. Вы также можете попробовать указать BrowsableAttribute и BindableAttribute на свойствах, чтобы заставить дизайнера отображать их. .

person thecoop    schedule 13.11.2009

Здесь вы можете делать разные вещи - вы можете (хотя это плохой ответ) выставлять рассматриваемые элементы управления в общедоступном интерфейсе - но я не уверен, что это хорошая идея.

Лично я бы просто повторно представил интересующие меня свойства, возможно, поместив их в другой [Category(...)], убедившись, что у них есть как сеттеры, так и геттеры.

Немного как:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

class MyControl : UserControl
{
    private Button button;
    private Label label;
    public MyControl()
    {
        button = new Button { Dock = DockStyle.Right, Text = "Click me" };
        label = new Label { Dock = DockStyle.Left};
        Controls.Add(button);
        Controls.Add(label);
    }
    [Category("Wonder Control")]
    public string CaptionText { get { return label.Text; } set { label.Text = value; } }
    [Category("Wonder Control")]
    public Color ButtonBackColor { get { return button.BackColor; } set { button.BackColor = value; } }
}
static class Program
{

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        using (Form form = new Form())
        using (MyControl ctrl = new MyControl())
        using (PropertyGrid grid = new PropertyGrid())
        {
            ctrl.ButtonBackColor = Color.Red;
            ctrl.CaptionText = "Caption";
            ctrl.Dock = DockStyle.Fill;
            grid.Dock = DockStyle.Right;
            form.Controls.Add(ctrl);
            form.Controls.Add(grid);
            grid.SelectedObject = ctrl;
            Application.Run(form);
        }

    }
}
person Marc Gravell    schedule 13.11.2009
comment
Как вы имеете в виду повторное разоблачение? Я могу выставить их в родительском классе с помощью [Category]. Можно ли как-то выставить их только в дочернем классе? - person Zoran Ivancevic; 13.11.2009

Если все кнопки в элементе управления будут иметь одинаковый внешний вид, почему бы не поместить свойство на уровень элемента управления, а установщик свойства распространит любые изменения на все кнопки? Кроме того, использование 30 отдельных элементов управления кнопками кажется слишком накладным... рассматривали ли вы возможность рисования меток для дней и обработки событий щелчка/наведения мыши, чтобы определить, когда нажат конкретный день?

person lJohnson    schedule 13.11.2009
comment
Это текущее решение. У меня есть свойства управления для цветов и их распространение на кнопки. Я рассматривал возможность рисования всего вручную, но я хочу, чтобы кнопки были активными объектами, а не просто графикой. Я бы хотел избежать проверки всего пользовательского элемента управления, чтобы определить выбранную дату. Также таким образом мне не нужно перерисовывать все даты при каждом клике, а только те, которые были изменены. - person Zoran Ivancevic; 13.11.2009
comment
Что вы подразумеваете под большим количеством накладных расходов? Проблемы с производительностью или просто много ненужного кода? Я думал о том, чтобы вручную создать класс кнопки, а не просто наследоваться от кнопки и реализовать только те функции, которые мне нужны. - person Zoran Ivancevic; 13.11.2009