簡體   English   中英

WPF:將附加的屬性從一個元素轉移到另一個?

[英]WPF: Transfer attached properties from one element to another?

我正在編寫WPF行為,該行為需要將現有的FrameworkElement包裝在Grid控件中。

舉個例子:

<Grid> <!-- Container Grid -->
  <Grid.RowDefinitions>
    <RowDefinition Height="1*"/>
    <RowDefinition Height="1*"/>
  </Grid.RowDefinitions>

  <Rectangle Height="100" Width="100" Grid.Row="1"/>

</Grid>

這是網格中的簡單矩形,包含兩行。 使用附加屬性,將矩形設置為顯示在網格的第1行中。

如果將行為附加到Rectangle,它將把Rectangle包裝在另一個Grid中,並像這樣影響可視樹:

<Grid> <!-- Container Grid -->
  <Grid.RowDefinitions>
    <RowDefinition Height="1*"/>
    <RowDefinition Height="1*"/>
  </Grid.RowDefinitions>

  <Grid> <!-- Wrapper Grid -->
    <Rectangle Height="100" Width="100" Grid.Row="1"/>
  </Grid>

</Grid>

我的問題是在這種情況下,現在包裝在新的Grid控件中的Rectangle將出現在Container Grid的行0中,而不是行1中。 矩形的“ Grid.Row”附加屬性需要重新分配給“包裝網格”控制。

我的問題是:是否有任何簡單的方法可以將所有附加屬性(例如Grid.Row等)從一個FrameworkElement傳輸到另一個? 還是有人可以提出解決此問題的更好方法?

我的行為需要確保將其附加到的元素包裝在面板控件(最好是網格)中(作為其子元素)。 該行為需要靈活,並且可以附加到任何類型的元素,可以在任何容器,面板,裝飾器等中使用; 因此,可以具有任何數量需要抵押的附加屬性。

僅供參考,我正在使用以下實用程序代碼執行包裝。 它在此階段處於實驗階段,只能處理父類型為Panel(網格)或Decorator(邊界)的元素:

        public static FrameworkElement WrapFrameworkElementWithGrid(FrameworkElement elementToWrap)
        {
            if (elementToWrap != null)
            {
                var container = new Grid();

                if (elementToWrap.Parent is Panel)
                {
                    // If the element is in a panel (grid, etc) then remove it,
                    // wrap it and replace it in the Children collection.
                    var panel = elementToWrap.Parent as Panel;

                    int childIndex = panel.Children.IndexOf(elementToWrap);

                    panel.Children.Remove(elementToWrap);

                    container.Children.Add(elementToWrap);

                    panel.Children.Insert(childIndex, container);

                    return container;
                }
                else if (elementToWrap.Parent is Decorator)
                {
                    // If the element is in a decorator (border, etc), then remove
                    // it, wrap it and set the Child as the container.
                    var decorator = elementToWrap.Parent as Decorator;

                    decorator.Child = null;

                    container.Children.Add(elementToWrap);

                    decorator.Child = container;

                    return container;
                }
                else
                {
                    // If the parent is of an unhandled type, then return the original element unwrapped.
                    return elementToWrap;
                }
            }
        }

您的問題對我不太清楚。 你到底在做什么? 您是在所有者網格中動態構建這些子級,還是已經有一個固定的xaml設計? 這個附加的dp問題僅與Grid.Row和Grid.Column屬性有關嗎? 您是否可以一開始就已經正確設計了樣板,這樣就不需要“包裝”了?

您想告訴我們更多有關您的打算嗎?

我知道這不僅僅是對問題的實際答案,而是評論,但是這里是您如何找到所有附加屬性的方法:

public IList<DependencyProperty> GetAttachedProperties(DependencyObject obj)
{
    List<DependencyProperty> attached = new List<DependencyProperty>();

    foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(obj,
        new Attribute[] { new PropertyFilterAttribute(PropertyFilterOptions.All) }))
    {
        DependencyPropertyDescriptor dpd =
            DependencyPropertyDescriptor.FromProperty(pd);

        if (dpd != null && dpd.IsAttached)
        {
            attached.Add(dpd.DependencyProperty);
        }
    }

    return attached;
}

因此,也許您可​​以在運行時加載Xaml,然后在決定顯示頁面之前進行更改。

看一下這個例子:

StreamReader mysr = new StreamReader("Page1.xaml");
DependencyObject rootObject = XamlReader.Load(mysr.BaseStream) as DependencyObject;
ButtoninXAML = LogicalTreeHelper.FindLogicalNode(rootObject, "button1") as Button ; 
ButtoninXAML.Click += new RoutedEventHandler(Button_Click); 
...

所有這些聽起來還是很酷的,我建議您首先重新考慮您的應用程序設計。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM