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

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

新規登録して質問してみよう
ただいま回答率
85.35%
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 クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

7414閲覧

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

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 クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

1クリップ

投稿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}
TN8001👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

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

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

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

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

xml:MainWindow.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>

cs

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}

xml:UserControl1.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>

cs:UserControl1.xaml.cs

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}

xml:UserControl2.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>

cs:UserControl2.xaml.cs

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

編集2023/07/29 05:40
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ry188472

2021/09/17 00:59

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

0

まず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

総合スコア797

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ry188472

2021/09/17 01:00

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問