2012-04-10 22 views
2

プロパティ値の継承をウィンドウからUserControlに利用しようとしています。私が理解する限り、(FrameworkPropertyMetadataOptions.Inheritsオプションと共に)付属のDependencyPropertyを宣言することで、これを実現できます。プロパティ値継承がUserControlで機能しない

MainWindow.xaml:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:WpfApplication1" Name="BobWindow"> 
    <Grid> 
     <Label Content="MainWindow" /> 
     <TextBox Height="23" HorizontalAlignment="Left" Margin="85,2,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Path=Test, ElementName=BobWindow}" /> 
     <my:UserControl1 HorizontalAlignment="Left" Margin="157,108,0,0" x:Name="userControl11" VerticalAlignment="Top" /> 
    </Grid> 
</Window> 

MainWindow.xaml.cs:

using System; 
using System.Windows; 

namespace WpfApplication1 
{ 
    public partial class MainWindow : Window 
    { 
     public static readonly DependencyProperty TestProperty = DependencyProperty.RegisterAttached 
      (
       "Test", 
       typeof(String), 
       typeof(MainWindow), 
       new FrameworkPropertyMetadata 
        (
         null, 
         FrameworkPropertyMetadataOptions.Inherits 
        ) 
      ); 
     public String Test 
      { 
       get { return (String)GetValue(TestProperty); } 
       set { SetValue(TestProperty, value); } 
      } 
     public MainWindow() 
     { 
      InitializeComponent(); 
      Test = "Yip!"; 
     } 
    } 
} 

UserControl1.xaml:

<UserControl x:Class="WpfApplication1.UserControl1" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300" Name="BobControl"> 
    <Grid> 
     <Label Content="UserControl1" /> 
     <TextBox Height="23" HorizontalAlignment="Left" Margin="85,2,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Path=Test, ElementName=BobControl}" /> 
    </Grid> 
</UserControl> 

UserControl1.xaml.cs:

using System; 
using System.Windows; 
using System.Windows.Controls; 

namespace WpfApplication1 
{ 
    public partial class UserControl1 : UserControl 
    { 
     public static readonly DependencyProperty TestProperty = DependencyProperty.RegisterAttached 
      (
       "Test", 
       typeof(String), 
       typeof(UserControl1), 
       new FrameworkPropertyMetadata 
        (
         null, 
         FrameworkPropertyMetadataOptions.Inherits 
        ) 
      ); 
     public String Test 
      { 
       get { return (String)GetValue(TestProperty); } 
       set { SetValue(TestProperty, value); } 
      } 

     public UserControl1() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

これを達成するための明示的な例は見つかりませんでした。 MainWindowとUserControl1でRegisterAttachedを使用するのは私の推測です。私には欠けているものがなければなりません!

UPDATE

私は、任意の構造で、私のコントロールを作成できるようにしたいと思い

、ツリーの最上部に値を設定し、デフォルト値はトリクルダウン(DataContextのがどのように機能するかに似ている)持っています。 TestPropertyがMainWindowとUserControl1の共通の祖先クラスにないときに可能ですか?

また、ソースクラスを参照しないようにしたいと思うこともあります。ウィンドウが表示されることもありますが、Windowsフォームのホストコントロールになることもあります。これは可能ですか?

RESOLVE

私は私の混乱が値の継承を実現するために非添付依存関係プロパティの構文を使用したいから茎と思います。そして、あなたはプロパティ値を継承したい場合は、MicrosoftのProperty Value Inheritanceページに従って、

string Value = this.Test; 

しかし:

<Window ... Test="Fred" /> 

そして、次の構文を使用して、ユーザーコントロールに継承された値にアクセス:私は以下のXAMLを使用していましたそれは添付プロパティを介している必要があります。

適切に再書かれたコード上の場合(静的getter/setterメソッドで、一度プロパティを宣言)その後、私のXAMLは次のようになります。

<Window ... my:MainWindow.Test="Fred" /> 

そして、ユーザーコントロール内の後ろに私のコードは次のようになります。これは

string Value = MainWindow.GetTest(this); 

答えて

2

ここで間違えたのは、プロパティを2回宣言することです。 UserControl1ではなく、MainWindowで宣言してください。そして、メインウィンドウで、このような静的なgetterメソッドとsetterメソッドを宣言:

public static string GetTest(DependencyObject obj) 
{ 
    return (String)obj.GetValue(TestProperty);  
} 

public static void SetTest(DependencyObject obj, string value) 
{ 
    obj.SetValue(TestProperty, value); 
} 

は、こちらの詳細情報についてcustom attached propertiesを取得します。

今のUserControl1は、メインウィンドウのどこかに要素ツリーであるとき、それは初期化された後のUserControl1で、次のような何かをしよう:

UserControl1 uc = this; // for example in a UserControl1 event handler 
string test = MainWindow.GetTest(uc); 

EDITを:あなたは、同様のUserControl1でプロパティを定義することができまたは他のクラスでも使用できます。また、それが添付プロパティであるため、そのクラスはDependencyObjectから派生する必要はありません。

+0

これはクールです。これはAddOwnerを使用するよりもきれいです... – Mitkins

+0

パフォーマンスについては、編集とノート[this](http://msdn.microsoft.com/en-us/library/ms753197.aspx#Making_a_Custom_Property_Inheritable)にも注意してください。 – Clemens

2

という意味の継承が誤解されているようです。です。コントロールに依存プロパティを設定した場合、そのプロパティの値はそのプロパティの値と同じになります。プロパティ自体を再宣言する必要はありません(まったく別のプロパティを作成するだけです)。

継承の例:コードで

<Window ... 
     xmlns:local="..." 
     local:MainWindow.Test="Lorem Ipsum"> 
    <Button Name="button"/> 

あなたは、ボタンの上に値を得ることができる必要があり、それがウィンドウのと同じでなければなりません。

var test = (string)button.GetValue(MainWindow.TestProperty); 
// test should be "Lorem Ipsum". 
関連する問題