在Control中使用DependencyProperty正确使用一次性

时间:2014-07-11 17:23:04

标签: c# wpf dependency-properties

我有很多带有文本的自定义TextBlocks,它们应该适合父容器的内容。 以下解决方案有效,但速度相当慢,我相信会造成内存泄漏。有没有更好的方法来使用OnMyDataChanged?是否可以使用此类型的依赖属性进行适当处理?

public class TrimmingTextBlock : TextBlock
{
    FrameworkElement _container; //StackPanel which holds this TextBlock
    public string LongText
    {
        get { return (string)GetValue(LongTextProperty); }
        set { SetValue(LongTextProperty, value); }
    }

    public static readonly DependencyProperty LongTextProperty =
                DependencyProperty.Register("LongText", typeof(string), typeof(TrimmingTextBlock), new PropertyMetadata(OnMyDataChanged));

    static void OnMyDataChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {           
        TrimmingTextBlock tb = obj as TrimmingTextBlock;            
        tb.ShortenIt(); //shorten text when text is changed
    }

    private void ShortenIt()
    {
        string mytext = LongText;
        _container = (FrameworkElement)this.Parent;        
        double _containerwidth = _container.ActualWidth;

        Task.Factory.StartNew(() =>
        {
            //do a CPU intensitive text manupulation so it fits _container
            ...
            //
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                this.Text = mytext;
            }), System.Windows.Threading.DispatcherPriority.Background);
        });
    }

    public TrimmingTextBlock()
    {
        this.SizeChanged += new SizeChangedEventHandler(container_SizeChanged);
    }
    void container_SizeChanged(object sender, SizeChangedEventArgs e)
    {
       ShortenIt(); //if container size changed (window resized) shorten the text again
    }
}

1 个答案:

答案 0 :(得分:0)

首先,为了绝对确保+=子句不会导致内存泄漏,您可以使用以下代码替换它:

protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
    base.OnRenderSizeChanged(sizeInfo);
    this.ShortenIt();
}

因此该事件的委托调用列表将为空。

第二 - 我认为您应该检查 CPU强化文本操作以提高其性能,以便将所有逻辑放在一个方法中,这将在 UI 线程,因为SizeChanged event可以在运行期间多次出现,并且每个事件都要创建TPL Task,(可以在UI线程上执行),以及这是您的主要开销可能来自的地方。