2012-04-17 10 views
6

wpfでusercontrolを使用すると、親要素の外側に到達できますか?例えば、私のユーザコントロールは、メインウィンドウのドックパネル内にカプセル化されたコントロール内に保持されているいくつかの一般的なものをリストしていますが、コントロールからアクセスしたいテキストボックスとボタンがメインウィンドウにありますこれは可能ですか?wpfの親要素を使用したUserControl?

それは時間のたくさん全体ではなく、ウィンドウの内容を変更し、すべてのユーザーコントロール内の同じテキストボックス/ボタンを表示する私を救うでしょう。誰かがこれの例を持っているなら、それは非常に高く評価されるでしょう。

+0

を示す別のユーザーコントロールは、この時、別の見ていた - あなたはデータバインディングや祖先のRelativeSourceを持つ親要素にアクセスしようとしましたか?もしそうなら、良い[SO答え](http://stackoverflow.com/questions/84278/how-do-i-use-wpf-bindings-with-relativesource)があります。それが良い解決策のように見えない場合は、問題を説明するコードを少し投稿してください。乾杯 – Berryl

答えて

3

はい、それは可能であり、ここで私がのDPを持っているのUserControlのうち、プレゼンテーションを作成するために使用されてきたいくつかのコードです。

私は少しでもそれを愛していませんが、それは動作します。私はこれがの偉大なの話題だと思うし、多分いくつかのコードがいくつかのより良い答えを得るのに役立つでしょう!

乾杯、
ベリー

ユーザーコントロールXAML

<Button x:Name="btnAddNewItem" Style="{StaticResource blueButtonStyle}" > 
    <StackPanel Orientation="Horizontal"> 
     <Image Source="{resx:Resx ResxName=Core.Presentation.Resources.MasterDetail, Key=bullet_add}" Stretch="Uniform" /> 
     <Label x:Name="tbItemName" Margin="5" Foreground="White" Padding="10, 0">_Add New [item]</Label> 
    </StackPanel> 
</Button> 
public partial class AddNewItemButton : UserControl 
{ 
    ... 

    #region Item Name 

    public static readonly DependencyProperty ItemNameProperty = DependencyProperty.Register(
     "ItemName", typeof(string), typeof(AddNewItemButton), 
     new FrameworkPropertyMetadata(OnItemNameChanged)); 

    public string ItemName 
    { 
     get { return (string)GetValue(ItemNameProperty); } 
     set { SetValue(ItemNameProperty, value); } 
    } 

    public string ButtonText { get { return (string) tbItemName.Content; } } 

    private static void OnItemNameChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
    { 
     // When the item name changes, set the text of the item name 
     var control = (AddNewItemButton)obj; 

     control.tbItemName.Content = string.Format(GlobalCommandStrings.Subject_Add, control.ItemName.Capitalize()); 
     control.ToolTip = string.Format(GlobalCommandStrings.Subject_Add_ToolTip, control.ItemName); 
    } 

    #endregion 

    #region Command 

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
     "Command", typeof(ICommand), typeof(AddNewItemButton), 
     new FrameworkPropertyMetadata(OnCommandChanged)); 

    public ICommand Command 
    { 
     get { return (ICommand)GetValue(CommandProperty); } 
     set { SetValue(CommandProperty, value); } 
    } 

    private static void OnCommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
    { 
     // When the item name changes, set the text of the item name 
     var control = (AddNewItemButton)obj; 
     control.btnAddNewItem.Command = control.Command; 
    } 

    #endregion 

} 
後ろ

ユーザーコントロールコード

​​

作曲

<UserControl ... 
     xmlns:uc="clr-namespace:Smack.Core.Presentation.Wpf.Controls.UserControls" 
     > 

    <DockPanel LastChildFill="True"> 
     ... 
     <uc:AddNewItemButton x:Name="_addNewItemButton" Margin="0,0,10 0" DockPanel.Dock="Right" /> 
     ... 
    </DockPanel> 
</UserControl> 

enter image description here

+1

かんたんな質問、WTFの回答です。 –

+1

答えに@Berryl +10!大きな努力とありがとう! @KendallFrey。 –

+1

それについて考えるのは簡単ではありませんが、あなたのためにシンプルで明確なコードを投稿するだけです。 – Berryl

3

より良いデザインパターンは、何かを変更する必要があるとき(イベントを通じて)、ユーザーコントロールを通知し、メインウィンドウを持っているだろう、それはいくつかの情報を必要とするとき(メソッドを介して)ウィンドウを依頼します。たとえば、UserControlが呼び出すことができるウィンドウにGetText()メソッドを、ウィンドウが登録するUserControlにChangeTextイベントを設定します。

アイデアは、常にウィンドウを制御し続けることです。この考え方を使用すると、将来的にアプリケーションを開発するのが容易になります。

+0

テキストボックスとボタンがある場合、例を使用してどのようにテキストをusercontrolに送信し、ボタンをクリックしたときにそのコントロールにテキストを入力しますか? –

+0

userControlでメソッドを作成します(たとえば、 'SetText(string text)')。 'button1_Click'では' myUserControl.SetText(myTextBox.Text) 'を呼び出します。usercontrol内の 'SetText'メソッドでは、あなたがusercontrol内のデータを設定するものを何でもすることができます。 –

2

あなたの質問に答えるために:バックコード内の親の部材を介して結合またはいずれかRelativeSourceを通じてはい、することができますいずれかのアクセス親コントロールを。しかし、良い答えは@KendallFreyの答えに似ています。 Light MVVMのようなフレームワークを採用し、メッセンジャークラスを使用するか、Kendallの説明どおりにイベントを使用してください。

関連する問題