我想寫一個自定義Panel
,可以使用裝飾器模板。這意味着它將有一些其他Panel
作爲屬性。當一些元素被添加到我的自定義面板中時,我想將其也添加到裝飾面板(存儲在屬性中),並且當某些元素被刪除時,我也想從裝飾面板中刪除它。我怎麼做 ?如何裝飾WPF面板?
是否有某種方法被重寫或某些事件在更改爲InternalCholdrens時觸發?
謝謝
編輯:Basicly我想要做的事就像this我想任何面板轉向動畫之一。所以我想用我的裝飾器來裝飾任何面板,使它變成動畫。
我想寫一個自定義Panel
,可以使用裝飾器模板。這意味着它將有一些其他Panel
作爲屬性。當一些元素被添加到我的自定義面板中時,我想將其也添加到裝飾面板(存儲在屬性中),並且當某些元素被刪除時,我也想從裝飾面板中刪除它。我怎麼做 ?如何裝飾WPF面板?
是否有某種方法被重寫或某些事件在更改爲InternalCholdrens時觸發?
謝謝
編輯:Basicly我想要做的事就像this我想任何面板轉向動畫之一。所以我想用我的裝飾器來裝飾任何面板,使它變成動畫。
我不完全理解這個問題的背景,但是你可以重寫OnVisualChildrenChanged
http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.onvisualchildrenchanged.aspx
我在想同樣的方式,但是這是一個正確的做法?OnVisualChildrenChanged也調用時,因爲綁定添加元素?這將是可取的。另一方面OnVisualChildrenChanged在添加邊框時發生了變化嗎?那是不可取的...... – drasto 2011-01-19 20:30:10
你不能做到這一點,很遺憾。
你會立即得到的是一個例外,說一個控件只能有一個邏輯父項。
雖然你可以做的是做雙重授權。你的小組委託測量/安排到另一個小組,並作爲回報,它提供了'鬼',它將作爲一個孩子,並將他們自己的措施/安排委託給你的小組的孩子。
下面的代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
public class DelegatePanel : Panel
{
private sealed class DelegateChild : FrameworkElement
{
readonly Func<Size, Size> measure;
readonly Func<Size, Size> arrange;
public DelegateChild(Func<Size,Size> measure, Func<Size,Size> arrange)
{
this.measure = measure;
this.arrange = arrange;
}
protected override Size MeasureOverride(Size availableSize)
{
return measure(availableSize);
}
protected override Size ArrangeOverride(Size finalSize)
{
return arrange(finalSize);
}
}
readonly Dictionary<UIElement, UIElement> delegateByChild = new Dictionary<UIElement,UIElement>();
public Panel LayoutPanel
{
get { return (Panel)GetValue(LayoutPanelProperty); }
set { SetValue(LayoutPanelProperty, value); }
}
public static readonly DependencyProperty LayoutPanelProperty =
DependencyProperty.Register("LayoutPanel", typeof(Panel), typeof(DelegatePanel), new PropertyMetadata(null));
protected override Size MeasureOverride(Size availableSize)
{
if(this.LayoutPanel==null)
return base.MeasureOverride(availableSize);
this.delegateByChild.Clear();
this.LayoutPanel.Children.Clear();
foreach (UIElement _child in this.Children)
{
var child = _child;
var delegateChild = new DelegateChild(
availableChildSize =>
{
child.Measure(availableChildSize);
return child.DesiredSize;
},
finalChildSize =>
{
return finalChildSize;
});
delegateByChild[child] = delegateChild;
this.LayoutPanel.Children.Add(delegateChild);
}
this.LayoutPanel.Measure(availableSize);
return this.LayoutPanel.DesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
if(this.LayoutPanel==null)
return base.ArrangeOverride(finalSize);
this.LayoutPanel.Arrange(new Rect(finalSize));
foreach (var kv in delegateByChild)
{
var child = kv.Key;
var delegateChild = kv.Value;
var position = delegateChild.TranslatePoint(default(Point), this.LayoutPanel);
Rect finalChildBounds = new Rect(
position,
delegateChild.RenderSize);
child.Arrange(finalChildBounds);
}
return this.LayoutPanel.RenderSize;
}
}
聲明:此沒有實現VirtualizingPanel。因此,雖然它在ItemsControl和該團伙內部工作 - 但對於大型館藏來說,其執行速度不夠快。
你期望能夠用「任何面板」做什麼樣的動畫?不同類型的面板(網格,畫布,堆棧面板,dockpanel等)對於如何在其中定位項目具有完全不同的功能。我沒有看到有一種通用的方式來做你所描述的...... – 2011-01-19 20:53:51
有。但那是我的知識,而且描述它並不容易。但技術細節似乎對我來說是一個問題:( – drasto 2011-01-19 21:12:14