我有很多带有文本的自定义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
}
}
答案 0 :(得分:0)
首先,为了绝对确保+=
子句不会导致内存泄漏,您可以使用以下代码替换它:
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
this.ShortenIt();
}
因此该事件的委托调用列表将为空。
第二 - 我认为您应该检查 CPU强化文本操作以提高其性能,以便将所有逻辑放在一个方法中,这将在 UI 线程,因为SizeChanged event可以在运行期间多次出现,并且每个事件都要创建TPL Task,(可以在UI线程上执行),以及这是您的主要开销可能来自的地方。