【问题标题】:How to connect a custom propertyGrid with a standard control in C#?如何在 C# 中将自定义 propertyGrid 与标准控件连接起来?
【发布时间】:2013-02-26 18:50:14
【问题描述】:

我正在创建一个图形程序,我希望用户能够更改他们创建的图形的外观。为他们提供更改系列颜色、数据点大小等的机会。我允许他们通过使用 propertyGrid 来做到这一点。然而,通过使用堆栈溢出的优秀人员的帮助,我能够将图表的所有属性导入我的属性网格;现在我不知道如何将我的图表连接到 propertyGrid,所以当我更改网格中的某些内容时,图表会发生变化。

到目前为止我有

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        magRadioBox.Checked = true;
        PropertyGrid propertyGrid1 = new PropertyGrid();
        propertyGrid1.CommandsVisibleIfAvailable = true;
        propertyGrid1.Text = "Graph and Plotting Options";
        propertyGrid1.PropertyValueChanged += propertyGrid1_PropertyValueChanged;

        this.Controls.Add(propertyGrid1);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.Text = "MY Plot Program";
        propertyGrid1.SelectedObject = chart1; 
    }

    private void button1_Click(object sender, EventArgs e)
    {
        //some code that is populating my chart(chart1) with data 
        //....chart1 being filled with data 
    }

    private void propertyGrid1_PropertyValueChanged(object s , PropertyValueChangedEventArgs e)
    {
        //Getting the MyChart instance from propertyGrid 
        MyChart myChart = (MyChart)(((PropertyGrid)s.SelectedObject);
        //Calling the method that will refresh my chart1 
        myChart.Invalidate(); 
    }

以上代码适用于我的表单。我的“MyChart”类代码是

namespace FFT_Plotter
{ 
    [DefaultPropertyAttribute("Text")]
    public class MyChart : Chart 
    {
        public event EventHandler PropertyChanged;

        private void OnPropertyChanged(object sender, EventArgs e)
        {
            EventHandler eh = propertyChanged;
            if(eh !=null)
            {
                eh(sender, e);
            }

            [BrowsableAttribute(false)]
            public new System.Drawing.Color BackColor
            {
                get { return BackColor; }//Here back color is just an example of a property, not necessarily one that I would make non-Browsable
                set 
                { 
                    base.BackColor = value; 
                    OnPropertyChanged(this,EventArgs.Empty);
                }
            }
        }
    }

上面的类让我有一个属性网格,它具有图表的所有属性,并允许我在我认为合适的时候隐藏这些属性。但是现在我一直在理解如何将我的 chart1 连接到我创建的网格。如果有人对如何做到这一点有任何建议,那将非常有帮助。

【问题讨论】:

    标签: c# .net winforms propertygrid


    【解决方案1】:

    您必须添加propertyGrid1.SelectedObject = myChartInstance;,然后您必须添加PropertyValueChanged 事件侦听器,每次用户通过PropertyGrid 更改myChartInstance 属性时都会触发该事件侦听器。因此,假设您希望在每次更改完成后重新绘制图表,代码应如下所示:

            private void propertyGrid1_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
            {
               // Redraw the chart.
               chart1.Invalidate();
            }
    
            public Form1()
            {
                InitializeComponent();
                magRadioBox.Checked = true;
                PropertyGrid propertyGrid1 = new PropertyGrid();
                propertyGrid1.CommandsVisibleIfAvailable = true;
                propertyGrid1.Text = "Graph and Plotting Options";
    
                // Create your chart.
                chart1 = new MyChart();
    
                // Attach your chart to Property Grid.
                propertyGrid1.SelectedObject = (MyChart) chart1;
                propertyGrid1.PropertyValueChanged += propertyGrid1_PropertyValueChanged;
    
                this.Controls.Add(propertyGrid1);
            }
    

    【讨论】:

    • 我认为 OP 意味着另辟蹊径。 IE。如何使图表组件反映对 ProeprtyGrid 中的属性所做的更改。例如。用户更改 PropertyGrid 中的背景颜色 -> 如何让图表的背景颜色作为响应?
    • 我不知道这将如何工作(并不是说它不起作用)。当您说“将图表的相同实例传递给属性网格和您的控件”时。你的意思是像public Form1()... MyChart myChartInstance = new MyChart(); chart1 = myChartInstance; propertyGrid.SelectedObject = myChartInstance; ... 这样的意思吗?如果不是,那么我想我不明白你的意思。
    • @user2023068 是的,这正是我的意思。此外,我更新了答案,因此它向您展示了在 myChartInstance 属性更改时通知您的控件的方式。
    • 我已经用我现在使用的代码更新了我的问题,但我仍然对如何“连接”我的控制器感到困惑。我想你的意思是private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e){ //somehow using myC.PropertyChanged and somehow chart1.Invalidate and somehow chart1.Refresh() }
    • @user2023068 这是实现它的一种方式。你的图表绘制算法和MyChart是同一类的吗?
    【解决方案2】:

    通过 StackOverflow 上伟大社区的帮助,这是我能够拼凑起来的答案,(站在巨人的肩膀上)

       public partial class Form1 : Form {
                public Form1()
                {
                    InitializeComponent();
                    magRadioBox.Checked = true;
                    PropertyGrid propertyGrid1 = new PropertyGrid();
                    propertyGrid1.CommandsVisibleIfAvailable = true;
                    propertyGrid1.Text = "Graph and Plotting Options";
                    propertyGrid1.PropertyValueChanged += propertyGrid1_PropertyValueChanged;
    
                    this.Controls.Add(propertyGrid1);
                } private void Form1_Load(object sender, EventArgs e) { this.Text = "MY Plot Program"; propertyGrid1.SelectedObject = chart1;  }
    
            private void button1_Click(object sender, EventArgs e)  {//some code that is populating my chart(chart1) with data   .... //chart1 being filled with data   }
    
            private void propertyGrid1_PropertyValueChanged(object s , PropertyValueChangedEventArgs e) { 
    myChart.Invalidate();  
    }
    

    这是MyChart 类的代码

    namespace FFT_Plotter
    { 
        [DefaultPropertyAttribute("Text")]// This is where the initial position of the grid is set 
        public class MyChart : Chart 
        {
            public event EventHandler PropertyChanged;
    private void OnPropertyChanged(object sender, EventArgs e)
    {
    EventHandler eh = propertyChanged;
    if(eh !=null)
    {
    eh(sender, e);
    }
            [BrowsableAttribute(false)]
            public new System.Drawing.Color BackColor
            {
                get { return BackColor; }//Here back color is just an example of a property, not necessarily one that I would make non-Browsable
                set { 
    base.BackColor = value; 
    OnPropertyChanged(this,EventArgs.Empty);
    }
            }
        }
    }
    

    这在 Form1.Designer.CS 中声明 chart1MyChart 而不是 System.Windows...Chart

    ...this.chart1  = new FFT_Ploter.MyChart(); ... private FFT_Plotter.MyChart chart1;  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-17
      • 2017-10-21
      • 2011-07-26
      • 2015-05-04
      • 1970-01-01
      相关资源
      最近更新 更多