35291


C#, WPFでアプリケーション開発を行っているのですが､2つのページで同じデータを共通で表示したいです｡  
バインディングを使うと思われるのですが､どうもうまくいきません…

例えば  
UserControl1.xamlにTreeView､  
UserControl2.xamlにUserControl1.xamlのTreeViewで選択したitem名が表示されるTextBox｡  
という構成にしたい場合

どのように各xamlにバインド定義を書くべきかご教授ください｡  
※情報が少ないかもしれません｡｡すみません｡


CC BY-SA 3.0
2017-06-05T04:33:44.437
35290
2017-06-07T00:27:31.597
12388
question
wpf xaml
WPF 2つ以上のXAMLでデータを共通で使いたい｡


各ユーザーコントロールに内部状態を公開するための[ **依存関係プロパティ**](https://msdn.microsoft.com/ja-
jp/library/ms752914\(v=vs.110\).aspx)を定義するのが良いと思います。

具体的な手順としては

  1. 各ユーザーコントロールのコードビハンドで`propdp`コードスニペットを実行し、依存関係プロパティを定義する。
  2. ユーザーコントロールのXAML内部の`TreeView`や`TextBox`で`RelativeSource`を用いて定義したプロパティにバインドする。
  3. ユーザーコントロールを含むビューでプロパティ同士が関連付けられるようにバインドする。

のようになります。

例えば単に`TreeView`もしくは`TextBox`を含むユーザーコントロールがあり、それぞれに`SelectedText`プロパティを定義する場合を考えます。依存関係プロパティは`propdp`からプロパティ型、プロパティ名、オーナー型、初期値の4か所を書き換えて以下のようになります。

[code]

    public string SelectedText
    {
        get { return (string)GetValue(SelectedTextProperty); }
        set { SetValue(SelectedTextProperty, value); }
    }
    
    public static readonly DependencyProperty SelectedTextProperty =
        DependencyProperty.Register("SelectedText", typeof(string), typeof(UserControl1), new PropertyMetadata(null));
    
[/code]

このプロパティに`TextBox`をバインドするためのXAMLは

[code]

    <UserControl
        x:Class="UserControl2"
        xmlns:local="clr-namespace:Hoge">
        <TextBox
            Text="{Binding SelectedText, RelativeSource={RelativeSource AncestorType=local:UserControl2}}" />
    </UserControl>
    
[/code]

となります。

一方`TreeView`の選択項目はバインド不可ですのでコードビハンドを使用して

[code]

    private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        // SelectedItemの型は実装に合わせて変える
        SelectedText = (((TreeView)sender).SelectedItem as TreeViewItem).Header?.ToString();
    }
    
[/code]

のように`TreeView.SelectedItemChanged`で設定を行います。

各コントロールがこのように実装されていれば、両者を使うビューでは

[code]

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <local:UserControl1
            x:Name="uc1" />
        <local:UserControl2
            Grid.Row="1"
            SelectedText="{Binding ElementName=uc1, Path=SelectedText}" />
    </Grid>
    
[/code]

のように直接コントロールのプロパティにバインドしたり、あるいは両プロパティを他の同一プロパティにバインドすることで値を同期させることが出来ます。


CC BY-SA 3.0
2017-06-05T04:46:56.950
35291
2017-06-05T05:12:02.963
2017-06-05T05:12:02.963
5750
5750
35290
answer