質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

解決済

WPFのUserControlに独自型の依存関係プロパティを設定してバインドしたい

ry188472
ry188472

総合スコア74

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

2回答

0グッド

2クリップ

3581閲覧

投稿2021/09/16 08:24

編集2021/09/16 08:25

.NET 5のWPFプロジェクトで外部から複数の値をバインドさせたいUserControlを作っています。そのためUserControlに独自型Textsの依存関係プロパティValueを作成し、UserControlの利用者となる親画面のxamlからValueをセットすることで、UserControlのコードビハインドで値を加工したりした上でUserControlのViewに反映させたいと考えています。
しかし、以下のコードで親画面(ここではコードビハインド)からTextsを作成してバインドさせても、画面に内容が反映されません。
独自型のバインドは不可能で、バインドしたい値が複数あったら1つ1つ依存関係プロパティを設定してバインドしなければならないのでしょうか?

※以下コードでは親画面側でReactiveProperty<Texts>を使ってバインドさせているつもりです。

Texts.cs

c#

1using System.Windows; 2using System.Windows.Controls; 3 4namespace WpfApp1 5{ 6 public class Texts 7 { 8 public int A { get; set; } = 5; 9 public string B { get; set; } = ""; 10 public double? C { get; set; } 11 } 12}

UserControl.xaml

xaml

1<UserControl x:Class="WpfApp1.UserControl1" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:WpfApp1" 7 mc:Ignorable="d" 8 d:DesignHeight="200" d:DesignWidth="200"> 9 <Grid Background="White"> 10 <Grid.RowDefinitions> 11 <RowDefinition Height="*"/> 12 <RowDefinition Height="*"/> 13 <RowDefinition Height="*"/> 14 </Grid.RowDefinitions> 15 <TextBlock Grid.Row="0" Text="{Binding Value.A}" Foreground="Black"/> 16 <TextBlock Grid.Row="1" Text="{Binding Value.B}" Foreground="Black"/> 17 <TextBlock Grid.Row="2" Text="{Binding Value.C}" Foreground="Black"/> 18 </Grid> 19</UserControl> 20

UserControl.xaml.cs

c#

1using System.Windows; 2using System.Windows.Controls; 3 4namespace WpfApp1 5{ 6 /// <summary> 7 /// UserControl1.xaml の相互作用ロジック 8 /// </summary> 9 public partial class UserControl1 : UserControl 10 { 11 public UserControl1() 12 { 13 InitializeComponent(); 14 } 15 16 public static readonly DependencyProperty ValueProperty = 17 DependencyProperty.Register( 18 "Value", 19 typeof(Texts), 20 typeof(UserControl1), 21 new PropertyMetadata(new Texts())); 22 23 public Texts Value 24 { 25 get { return (Texts)GetValue(ValueProperty); } 26 set { SetValue(ValueProperty, value); } 27 } 28 } 29}

MainWindow.xaml

xaml

1<Window x:Class="WpfApp1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <Grid> 10 <Grid.ColumnDefinitions> 11 <ColumnDefinition Width="*"/> 12 <ColumnDefinition Width="*"/> 13 <ColumnDefinition Width="*"/> 14 </Grid.ColumnDefinitions> 15 <local:UserControl1 Grid.Column="0" Value="{Binding ValueA.Value}"/> 16 <local:UserControl1 Grid.Column="1" Value="{Binding ValueB.Value}"/> 17 <local:UserControl1 Grid.Column="2" Value="{Binding ValueC.Value}"/> 18 </Grid> 19</Window>

MainWindow.xaml.cs

c#

1using Reactive.Bindings; 2using System.Windows; 3 4namespace WpfApp1 5{ 6 /// <summary> 7 /// Interaction logic for MainWindow.xaml 8 /// </summary> 9 public partial class MainWindow : Window 10 { 11 public MainWindow() 12 { 13 InitializeComponent(); 14 ValueA = new ReactiveProperty<Texts>(new Texts { A = 1, B = "Ab", C = 10.0 }); 15 ValueB = new ReactiveProperty<Texts>(new Texts { A = 2, B = "Bb", C = 222.22 }); 16 ValueC = new ReactiveProperty<Texts>(new Texts { A = 3, B = "Cb", C = null }); 17 } 18 19 public ReactiveProperty<Texts> ValueA { get; } 20 public ReactiveProperty<Texts> ValueB { get; } 21 public ReactiveProperty<Texts> ValueC { get; } 22 } 23}

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答2

1

ベストアンサー

なぜかこういう作りにする方が多いですよね(過去記事等のミスリードなんだと思います)

この例だと依存関係プロパティを作る必要はありません。DataContextTextsを渡すだけです。

どうしてもというならRelativeSourceElementNameで、UserControl1自身を引っ張ってくる必要があります。

個人的にはユーザーコントロールで、依存関係プロパティが必要になることはほとんどないですね(カスタムコントロールでは多用しますが)

xaml

1<Window 2 x:Class="Questions359857.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions359857" 6 Width="800" 7 Height="450"> 8 <Window.Resources> 9 <DataTemplate DataType="{x:Type local:Texts}"> 10 <local:UserControl2 /> 11 </DataTemplate> 12 </Window.Resources> 13 <Grid> 14 <Grid.ColumnDefinitions> 15 <ColumnDefinition /> 16 <ColumnDefinition /> 17 <ColumnDefinition /> 18 </Grid.ColumnDefinitions> 19 <GroupBox Header="Original"> 20 <local:UserControl1 Value="{Binding ValueA.Value}" /> 21 </GroupBox> 22 <GroupBox Grid.Column="1" Header="DataContext"> 23 <local:UserControl2 DataContext="{Binding ValueB.Value}" /> 24 </GroupBox> 25 <GroupBox Grid.Column="2" Header="DataTemplate"> 26 <ContentControl Content="{Binding ValueC.Value}" /> 27 </GroupBox> 28 </Grid> 29</Window>

C#

1using Reactive.Bindings; 2using System.Windows; 3 4namespace Questions359857 5{ 6 public class Texts 7 { 8 public int A { get; set; } = 5; 9 public string B { get; set; } = ""; 10 public double? C { get; set; } 11 } 12 13 public partial class MainWindow : Window 14 { 15 public ReactiveProperty<Texts> ValueA { get; } = new(new Texts { A = 1, B = "Ab", C = 10.0 }); 16 public ReactiveProperty<Texts> ValueB { get; } = new(new Texts { A = 2, B = "Bb", C = 222.22 }); 17 public ReactiveProperty<Texts> ValueC { get; } = new(new Texts { A = 3, B = "Cb", C = null }); 18 19 public MainWindow() 20 { 21 InitializeComponent(); 22 DataContext = this; 23 } 24 } 25}

xaml

1<UserControl 2 x:Class="Questions359857.UserControl1" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions359857" 6 x:Name="userControl1"> 7 <StackPanel> 8 <HeaderedContentControl Header="A"> 9 <TextBox Text="{Binding Value.A, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type local:UserControl1}}}" /> 10 </HeaderedContentControl> 11 <HeaderedContentControl Header="B"> 12 <TextBox Text="{Binding Value.B, UpdateSourceTrigger=PropertyChanged, ElementName=userControl1}" /> 13 </HeaderedContentControl> 14 <HeaderedContentControl DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:UserControl1}}}" Header="C"> 15 <TextBox Text="{Binding Value.C, UpdateSourceTrigger=PropertyChanged}" /> 16 </HeaderedContentControl> 17 </StackPanel> 18</UserControl>

C#

1using System.Windows; 2using System.Windows.Controls; 3 4namespace Questions359857 5{ 6 public partial class UserControl1 : UserControl 7 { 8 public Texts Value { get => (Texts)GetValue(ValueProperty); set => SetValue(ValueProperty, value); } 9 public static readonly DependencyProperty ValueProperty 10 = DependencyProperty.Register(nameof(Value), typeof(Texts), typeof(UserControl1), 11 new PropertyMetadata(new Texts())); 12 13 public UserControl1() => InitializeComponent(); 14 } 15}

xaml

1<UserControl 2 x:Class="Questions359857.UserControl2" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 5 <StackPanel> 6 <HeaderedContentControl Header="A"> 7 <TextBox Text="{Binding A, UpdateSourceTrigger=PropertyChanged}" /> 8 </HeaderedContentControl> 9 <HeaderedContentControl Header="B"> 10 <TextBox Text="{Binding B, UpdateSourceTrigger=PropertyChanged}" /> 11 </HeaderedContentControl> 12 <HeaderedContentControl Header="C"> 13 <TextBox Text="{Binding C, UpdateSourceTrigger=PropertyChanged}" /> 14 </HeaderedContentControl> 15 </StackPanel> 16</UserControl>

C#

1using System.Windows.Controls; 2 3 4namespace Questions359857 5{ 6 public sealed partial class UserControl2 : UserControl 7 { 8 public UserControl2() => InitializeComponent(); 9 } 10}

投稿2021/09/16 22:14

TN8001

総合スコア8046

ry188472👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

ry188472

2021/09/17 00:59

回答ありがとうございます。TN8001さんのコードを参考に、`Texts`クラスのバインドを行うことができました。うまくいくことを依存関係プロパティを使う場合とDataContextでやる場合の両方で確認できました。

1

まずUserControl側のxamlの記述ですが、

UserControl.xaml

xaml

1 <TextBlock Grid.Row="0" Text="{Binding Value.A}" Foreground="Black"/> 2 <TextBlock Grid.Row="1" Text="{Binding Value.B}" Foreground="Black"/> 3 <TextBlock Grid.Row="2" Text="{Binding Value.C}" Foreground="Black"/>

これだとUserControlに設定されているDataContextのValueプロパティをBindしてることになるかと思います

またUserControlを配置しているWindow側のxamlの記述ですが、

MainWindow.xaml

xaml

1 <local:UserControl1 Grid.Column="0" Value="{Binding ValueA.Value}"/> 2 <local:UserControl1 Grid.Column="1" Value="{Binding ValueB.Value}"/> 3 <local:UserControl1 Grid.Column="2" Value="{Binding ValueC.Value}"/>

これも同様にMainWindowに設定されているDataContextのValueA,ValueB,ValueCプロパティをBindしてることになるかと思います

投稿2021/09/16 10:19

ebiryo

総合スコア795

ry188472👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

ry188472

2021/09/17 01:00

ご回答ありがとうございます。WPFは最近さわりはじめたのでDataContextについて全然理解できてないのだと思います。きちんと調べさせていただきます!

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです