Как перерисовать или обновить в OnRender?

Я хочу нарисовать что-то динамически. Следующий код показывает мой OnRender. Я устанавливаю DrawItem где-нибудь в моей программе, где мне это нужно. Но когда я звоню DrawItem =5; что мне нужно позвонить, чтобы вызвать OnRender?

protected override void OnRender(DrawingContext drawingContext)
{
    switch (DrawItem)
    {
        case 1:
            //Draw Item 
            break;
        case 2:
            //Draw Item 
            break;
        case 3:
            //Draw Item 
            break;
        case 4:
            //Draw Item 
            break;
        case 5:
            //Draw Item 
            break;
    }
    base.OnRender(drawingContext)
}

public int DrawItem { get; set; }

4 ответа

Решение

Ваш вопрос не ясен, но насколько я понимаю, вы, похоже, запрашиваете метод обновления визуальных элементов после обновления переменных чертежа. После обновления переменных рисования вы можете использовать следующее:

this.InvalidateVisual();

и с собственностью:

private int drawItem;
pulic int DrawItem
{
 get {return drawItem;}
 set 
 {
    drawItem=value;
    this.InvalidateVisual();
 }
}

Если размер вашего элемента управления изменится, вы можете использовать InvalidateVisual()Однако имейте в виду, что это приводит к довольно дорогой переделке вашего интерфейса. Если размер вашего контроля остается прежним, вы не должны звонить InvalidateVisual(),

Более эффективный способ обновить ваш интерфейс - создать DrawingGroup "бэк-магазин" и добавить его в DrawingContext в течение OnRender(), Затем вы можете обновить его в любое время, используя DrawingGroup.Open()и WPF обновит ваш пользовательский интерфейс.

Если это звучит странно, помните, что WPF - это сохраненная система рисования. Это означает OnRender() лучше назвать AccumulateDrawingObjects(), На самом деле он накапливает дерево живых объектов рисования, некоторые из которых (например DrawingGroup, RenderTargetBitmap и WriteableBitmap) могут быть обновлены позже.

Вот как это выглядит:

DrawingGroup backingStore = new DrawingGroup();

protected override void OnRender(DrawingContext drawingContext) {      
    base.OnRender(drawingContext);            

    Render(); // put content into our backingStore
    drawingContext.DrawDrawing(backingStore);
}

// I can call this anytime, and it'll update my visual drawing
// without ever triggering layout or OnRender()
private void Render() {            
    var drawingContext = backingStore.Open();
    Render(drawingContext);
    drawingContext.Close();            
}

Я столкнулся с подобной проблемой и нашел еще более элегантное решение. Определите свойство DependencyProperty следующим образом:

public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register("PropertyName", typeof(PropertyType), typeof(PropertyElementType), new FrameworkPropertyMetadata(DefaultPropertyValue, FrameworkPropertyMetadataOptions.AffectsRender));

Ключ здесь заключается в следующем:

FrameworkPropertyMetadataOptions.AffectsRender

Так что теперь свойство может быть установлено в XAML и обновляется автоматически при изменении.

http://msdn.microsoft.com/de-de/library/ms598919(v=vs.100).aspx

Вы должны вызвать InvalidateVisual для элемента управления, который должен быть обновлен. Но, как вы понимаете, вызов InvalidateVisual вызывает полный цикл компоновки, поэтому по соображениям производительности убедитесь, что ваш холст или все, что вы хотите рисовать, не содержит или содержит только несколько дочерних элементов.

Другие вопросы по тегам