2012-04-14 18 views
4

我開發了一種改變AssociatedObject的Clip屬性的行爲。當我運行應用程序時,一切都很好。但是當我在Blend中查看頁面時,它看起來像行爲不會影響其關聯的對象。Silverlight混合行爲在設計時沒有附加到

我試圖通過將Visual Studio 2010調試器附加到其進程並在行爲的OnAttached方法上設置一個斷點來「調試」混合,但斷點永遠不會到達。就好像融合可以防止這種行爲在設計時被附着。

有沒有辦法解決它?

乾杯,

+0

據我所知,這個問題也出現在WPF中的Visual Studio 2013(它的Blend內部集成了它的設計器)。我有這個問題,因爲我在這個環境中有類似的情況。 – FrankyB 2015-01-22 13:37:52

回答

2

我終於找到了一個可行的方法,但有一個很大的警告,我把這個答案的結尾。這裏是我的CustomAttachManager:

public class CustomAttachManager : DependencyObject 
{ 
    #region Object CustomAttachManager.Attached = null 

    public static IAttachedObject GetAttached(DependencyObject obj) { return (IAttachedObject)obj.GetValue(AttachedProperty); } 
    public static void SetAttached(DependencyObject obj, IAttachedObject value) { obj.SetValue(AttachedProperty, value); } 

    public static readonly DependencyProperty AttachedProperty = 
     DependencyProperty.RegisterAttached("Attached", typeof(IAttachedObject), typeof(CustomAttachManager), new PropertyMetadata(null, StaticHandleAttachedChanged)); 

    static void StaticHandleAttachedChanged(DependencyObject self, DependencyPropertyChangedEventArgs args) 
    { 
     var ov = (IAttachedObject)args.OldValue; 
     var nv = (IAttachedObject)args.NewValue; 

     if (ov != null) ov.Detach(); 
     if (nv != null) nv.Attach(self); 
    } 
    #endregion 
} 

然後,您可以用它來連接行爲,就像這樣:

<my:CustomAttachManager.Attached> 
    <my:RedBackgroundBehavior></my:RedBackgroundBehavior> 
</my:CustomAttachManager.Attached> 

我的例子行爲改變面板的背景爲紅色,這是設計師可見。

剩餘的問題是多行爲的情況。我可以拿出最好的解決辦法是代理:

[ContentProperty("Children")] 
public class MultipleBehavior : Behavior<DependencyObject> 
{ 
    DependencyObjectCollection<IAttachedObject> children = new DependencyObjectCollection<IAttachedObject>(); 
    public DependencyObjectCollection<IAttachedObject> Children { get { return children; } } 

    protected override void OnAttached() 
    { 
     foreach (var child in Children) child.Attach(AssociatedObject); 
    } 

    protected override void OnDetaching() 
    { 
     foreach (var child in Children) child.Detach(); 
    } 
} 

可以這樣使用:

<my:CustomAttachManager.Attached> 
     <my:MultipleBehavior> 
      <my:RedBackgroundBehavior /> 
      <my:SupriseBehavior /> 
     </my:MultipleBehavior> 
    </my:CustomAttachManager.Attached> 

代理擁有的東西后添加的,因爲它不會妥善處理行爲缺陷已經連接上了,但這在經典用例中不會發生。

需要注意的是,我不知道如何使Blend顯示對象樹中的行爲。無法使用「AlternateContentProperty」,因爲它不適用於CustomAttachManager使用的附加屬性。

我會更新這個答案,我應該找到這個問題的答案。

+0

Thnx,John,這實際上是一個很好的解決方案。我也爲Win8商店應用程序(沒有本地行爲支持)實現了我自己的行爲集合,並且實際上設法讓他們在設計時間內工作,雖然有多個行爲存在傳遞數據上下文的問題,正如您已經注意到的那樣在你的解決方案。 – 2013-12-18 15:40:00

+0

@KobiHari如果你有什麼東西可以鏈接到你用Win8商店xaml完成的事情,那麼如果你在這裏發佈這樣的鏈接會很酷。我還沒有嘗試過這一點,以及它如何與Silverlight進行比較;也許在將來的某個時刻我不得不這樣做。 – John 2014-01-19 13:49:15

0

我不知道,但我認爲一旦行爲被「附加」的相關對象只能影響。這在「OnAttached」事件期間被調用,我不相信這個事件在設計時被調用。據我所知,控制的設計時間變化發生在初始化/創建階段。 OnAttached發生在所有這些事件發生之後(因此AssociatedObject可用於操作的原因),並因此導致行爲在設計時更改控件時很困難。我並不是說這是不可能的,但是從控制的生命週期以及行爲的明顯設計來看,這種方法似乎很難。 解決方案:

  • 採取模板操作的方法。附上您設計的自定義樣式或資源字典密鑰,以創建您所尋找的印象。
  • 在Visual Studio中創建一個自定義控件,該控件公開可以將其他控件綁定到的屬性。讓這個自定義控件操作這個「屬性」,即在它的一個初始化方法中使用clip屬性控制你的控件。例如,在InitializeComponent期間,檢查內容是否被加載,然後調用一個方法來調整你的「Clip」屬性。閱讀上一個Silverlight控件的生命週期,這可能會幫助你 - http://stuff.seans.com/2009/03/23/hello-silverlight-world-part-3-the-lifecycle-of-a-silverlight-control/

就像我說的,我不知道這裏的答案,但我要說的是 - 如果解決方案似乎過於複雜,有可能是一個更清潔的方法;)

+0

尼爾,正如我寫的,我知道行爲的OnAttached沒有被調用,問題是爲什麼。我可以選擇很多不同的方法(例如,我嘗試過的附加屬性,以及在設計時間和運行時間都有效的附加屬性)。由於附加行爲是基於附加屬性的,因此它們在設計時的行爲表現有點奇怪。我想知道的是,如果有人知道爲什麼在設計時不調用OnAttached方法,並且我可以做一些不同的事情來使其調用。 – 2012-04-15 15:35:05

+0

啊。我相信這不是設計時間生命週期的一部分。我記得當我正在開發一個ASP.NET項目時遇到了類似的情況。我正在做一個自定義的組合框,因爲我希望在設計時間稍微預先弄好,然後我意識到有些方法只是在運行時纔會調用。我一直無法找到文檔說明在設計時哪些方法被調用,哪些方法在運行時被調用。 – 2012-04-15 17:31:13

+0

我最後一個打賭是確保你使用的是DependencyProperties,而不是普通的屬性。除此之外,它在VS 2010中的做法是否一樣? @KobiHari – 2012-04-15 17:39:59

相關問題