Пользовательский компонент

 
0
 
.NET
ava
TYUS | 19.06.2010, 21:23
Здравствуйте! Помогите, пожалуйста, разобраться. Написала компонент FuncGrafic построения графика функции на основе PictureBox. У компонента есть свойство Points массив точек типа PointF. Устанавливаю компонент на форму. И по кнопке BitButton ввожу новые значения в Points, массив заполняется, но изображение компонента в зависимости от изменений массива точек не меняется. Как решить эту проблему подскажите, пожалуйста. Заранее благодарна
Ответы (8)
ava
diadiavova | 21.06.2010, 22:23 #
А почему не воспользоваться готовым контролом?
http://www.microsoft.com/downloads/details...a8-910ae6ea442c
http://code.msdn.microsoft.com/mschart

ava
jonie | 21.06.2010, 22:31 #
Цитата


У компонента есть свойство Points массив точек типа PointF. Устанавливаю компонент на форму. И по кнопке BitButton ввожу новые значения в Points, массив заполняется, но изображение компонента в зависимости от изменений массива точек не меняется

Если у вас просто массив, то надо как-то говорить компоненту "пора перерисоваться"... вероятно вы этого не делаете. Оформите массив свойством, и сделайте при изменении его перерисовку грфика. Т.е. нечто вроде:

class MyMegaPlotter {
private double[] points;
public double[] Points {get {....} set { points = value; RepaintAll(); }
}
конечно, "по уму" хорошо бы при изменении конкретного элемента массива делать отрисовку, но тогда надо рисовать свой класс, где перегружать индексатор (this[int index]), и уже из него вызывать событие "коллекция изменена" (например, реализовава INotifyPropertyChanged или свой event....
ava
TYUS | 22.06.2010, 20:09 #
Цитата


Оформите массив свойством, и сделайте при изменении его перерисовку грфика. Т.е. нечто вроде:Код



class MyMegaPlotter {

private double[] points;

public double[] Points {get {....} set { points = value; RepaintAll(); }

}


Я так и делаю, но очевидно, что -то не учитываю. Потому что, рисую я BitMap - е , BitMap создается, но пустой

Добавлено позднее:
Цитата


А почему не воспользоваться готовым контролом?

http://www.microsoft.com/downloads/details...a8-910ae6ea442c

http://code.msdn.microsoft.com/mschart


Спасибо за ссылочки, я изучаю С# и потому надо создать компонент самой
ava
diadiavova | 22.06.2010, 22:46 #
Цитата (TYUS @ 22.6.2010, 21:09 findReferencedText)
Спасибо за ссылочки, я изучаю С# и потому надо создать компонент самой

Тогда всё стандартно: прорисовку надо выполнять в методе OnPaint (или если это делается не в производном классе, то в обработчике события Paint), а при изменении содержимого, которое надо прорисовать, вызывается метод Invalidate контрола(это необязательно должен быть пикчербокс, даже лучшее сли не он smile )
ava
TYUS | 23.06.2010, 22:38 #
Цитата


Тогда всё стандартно: прорисовку надо выполнять в методе OnPaint (или если это делается не в производном классе, то в обработчике события Paint), а при изменении содержимого, которое надо прорисовать, вызывается метод Invalidate контрола(это необязательно должен быть пикчербокс, даже лучшее сли не он )


Дело в том, что компонент отображает график функции, пока массив точек формируется в самом массиве, когда я выношу формирование массива из компонента и ввод значений происходит с помощью свойства Points компонента, не смотря на то , что свойство компонента Points заполняется массивом точек, отрисовки не происходит. Я понимаю, что не правильно формирую свойство компонента, но нигде не могу найти примера
ava
jonie | 24.06.2010, 01:26 #
Нарисовал поясняющий пример.
Собственно думаю по нему станет понятно что когда вызывается и, главное, зачем....

class Program
{
class Point
{
public delegate void Changed(Point pt);
public event Changed OnChanged;

private void FirechangedEvent(string descr)
{
Console.WriteLine("Точка поменялась (" + descr + ")");
if (null != OnChanged)
OnChanged(this);
}
private int x, y;

public int X { get { return x; } set { if (x != value) { x = value; FirechangedEvent("X"); } } }
public int Y { get { return y; } set { if (y != value) { y = value; FirechangedEvent("Y"); } } }

public override string ToString()
{
return "{"+X + ";" + Y + "}";
}
}

class PointArray
{
public delegate void Changed(PointArray pa, Point pt); //объект, и что поменялось в нём
public event Changed OnChanged;

private void p_OnChanged(Point pt)
{
FirechangedEvent(pt, "Поменяли");
}

private void FirechangedEvent(Point pt, string descr)
{
Console.WriteLine("Массив поменялся :" + descr + " (Изменилась точка " + pt + ")");
if (null != OnChanged)
OnChanged(this, pt);
}

private readonly List<Point> points = new List<Point>();

public Point this[int idx]
{
get { return points[idx]; }
}

public void Add(Point p) { points.Add(p); p.OnChanged += p_OnChanged; FirechangedEvent(p, "Добавили"); }

public void Remove(Point p) { points.Remove(p); p.OnChanged -= p_OnChanged; FirechangedEvent(p, "Удалили"); }

public int Count { get { return points.Count; } }
}

class Plotter
{
PointArray pa = new PointArray();

public Plotter()
{
pa.OnChanged += new PointArray.Changed(pa_OnChanged);
}

void pa_OnChanged(PointArray pa, Point pt)
{
Console.WriteLine("Надо перерисоваться!");
}

public void ReinitPlotter()
{
//1. чистим старый массив
while( pa.Count> 0)
{
pa.Remove(pa[0]);
}

//2. добавляем новые
Random rnd = new Random();
for (int i = 0; i < 5 ; i++)
{
var pt = new Point { X = rnd.Next(10), Y = rnd.Next(10) };
pa.Add( pt );
}
}
}

static void Main(string[] args)
{
Plotter pt = new Plotter();
pt.ReinitPlotter();
Console.WriteLine("Переинициализируемсмя ...");
pt.ReinitPlotter();
}
}

ava
diadiavova | 24.06.2010, 10:45 #
TYUS, из последнего поста я ничего не понял. Что значит
Цитата (TYUS @ 23.6.2010, 23:38 findReferencedText)
массив точек формируется в самом массиве

???
Это всё равно, что сказать "вода кипит в самой воде". Фраза лишена смысла.
Цитата (TYUS @ 23.6.2010, 23:38 findReferencedText)
ввод значений происходит с помощью свойства Points

Что такое свойство Points? Это массив точек что ли? Какого типа свойство? smile
Если нужно чтобы через свойство Points вводился массив точек и тут же отображался в виде линиии, проходящей через эти точки, то сделать надо примерно так

public partial class Chart : Control
{
public Chart()
{
InitializeComponent();
}

protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
if (Points != null)
{
pe.Graphics.Clear(Color.White);
pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
pe.Graphics.DrawCurve(new Pen(Color.Red,2),this.Points);
}
}
private Point[] points;
public Point[] Points
{
get
{
return points;
}
set
{
points = value;
this.Invalidate();
}
}
}
ava
TYUS | 25.06.2010, 00:06 #
jonie, спасибо попробую

Добавлено позднее:
Цитата


Цитата(TYUS @ 23.6.2010, 23:38 )
  массив точек формируется в самом массиве





???

Это всё равно, что сказать "вода кипит в самой воде". Фраза лишена смысла.



это опечатка, я имела ввиду массив точек формируется в самом компоненте


Цитата


Что такое свойство Points? Это массив точек что ли? Какого типа свойство?


Я писала, что свойство Points - это массив точек типа PointF

Добавлено позднее:
Сегодня поняла, в чем проблема, но как ее решить не знаю. Как выяснилось, в приложении я заполняю свойство FuncGrafic1.Points (где FuncGrafic1 и есть мой компонент), массивом точек, проверила, оно действительно заполнено, но в компонент этот массив точек не передается, в компоненте пустой массив точек, соответственно ничего не прорисовывается. Если массив прописывать в самом компоненте в свойстве, все прорисовывается, а из вне почему-то не берет
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
  jonie   TYUS ava  diadiavova
advanced
Отправить