2014-01-08 43 views
0

有沒有辦法在破壞時重新啓用xaml中的屬性繼承?如何恢復xaml中破損的屬性繼承

這裏是CustomControl:

public class CustomControl : DataGrid 
{ 
    static CustomControl() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl))); 
    } 

    public object Item 
    { 
     get { return (object)GetValue(ItemProperty); } 
     set { SetValue(ItemProperty, value); } 
    } 

    public static readonly DependencyProperty ItemProperty = 
     DependencyProperty.Register("Item", typeof(object), typeof(CustomControl), new PropertyMetadata(null)); 

    public object ContentControl 
    { 
     get { return (object)GetValue(ContentControlProperty); } 
     set { SetValue(ContentControlProperty, value); } 
    } 

    public static readonly DependencyProperty ContentControlProperty = 
     DependencyProperty.Register("ContentControl", typeof(object), typeof(CustomControl), new PropertyMetadata(OnContentChanged)); 

    private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var control = d as CustomControl; 

     if (e.OldValue != null) 
     { 
      control.RemoveLogicalChild(e.OldValue); 
     } 

     control.AddLogicalChild(e.NewValue); 
    } 
} 

XAML中的一部分。 (Generic.xaml)

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:WpfApplication"> 

<Style TargetType="{x:Type local:CustomControl}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:CustomControl}"> 
       <ContentPresenter DataContext="{TemplateBinding Item}" ContentSource="ContentControl"/> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

而這是主窗口:

<TabControl> 
    <TabItem Header="Skip this tab..."> 
    </TabItem> 
    <TabItem Header="Here..."> 
     <WpfApplication:CustomControl DataContext="{Binding}" x:Name="CustomControl" Item="{Binding InnerViewModel}"> 
      <WpfApplication:CustomControl.ContentControl> 
       <!-- The DataContext is not inherited... --> 
       <TextBlock Text="{Binding InnerName}" /> 
      </WpfApplication:CustomControl.ContentControl> 
     </WpfApplication:CustomControl> 
    </TabItem> 
</TabControl> 

最後,對應的ViewModels:

public class ViewModel 
{ 
    public string Name { get; set; } 

    public InnerViewModel InnerViewModel { get; set; } 

    public ViewModel() 
    { 
     InnerViewModel = new InnerViewModel(); 
     Name = "ViewModel"; 
    } 
} 

public class InnerViewModel 
{ 
    public string InnerName { get; set; } 

    public InnerViewModel() 
    { 
     InnerName = "InnerViewModel"; 
    } 
} 

在此先感謝!

回答

0

在你的例子中沒有中斷的依賴項屬性值繼承,而是你完全拋棄了DataContext。

刪除此DataContext = "{Binding}"

DataContext的是已經存在。你是額外的綁定DataContext自己。這毀了東西。

但是,如果通過刪除DataContext = "{Binding}"仍然無法向ContentControl提供數據,請嘗試設置ContentPropertyAtttribute。

要了解更多有關這個屬性,請檢查此鏈接了:

http://msdn.microsoft.com/en-us/library/system.windows.markup.contentpropertyattribute%28v=vs.110%29.aspx

+0

謝謝你,但我只用1個含量DP爲簡單起見,使這個例子,所以使長話短說,我有一個包含多個內容dependecy屬性 - 一個用於添加DataGrid的內容,一個是編輯和一個用於刪除。在這種情況下,無法放置多個[ContentProperty]屬性。 – user3049133

+0

噢好吧,在這種情況下,您可以離開ContentPropertyAttribute,並刪除綁定到DataContext,你應該沒問題。 –

+0

DataContext不是InnerViewModel的「Item」。如果仔細看一下Generic.xaml,你會看到「」。 DataContext =「{TemplateBinding Item}」的部分不起作用,如果我註釋掉control.AddLogicalChild(e.NewValue);它將工作。但是這會破壞我使用元素名稱綁定的能力。 – user3049133

0

最後,一個骯髒的解決方案發生我的腦海裏。我不認爲這是正確的方式,但你可以手動設置DataContext。

public static readonly DependencyProperty ItemProperty = 
    DependencyProperty.Register("Item", typeof(object), typeof(CustomControl), new PropertyMetadata(OnItemPropertyChanged)); 

    private static void OnItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var control = d as CustomControl; 
     var frameworkElement = control.ContentControl as FrameworkElement; 
     if (frameworkElement != null) 
     { 
      frameworkElement.DataContext = control.Item; 
     } 
    }