前提・実現したいこと
Window(Prism)に対して動的にUsercontrolを配置し、Windowからバインドさせた値を配置するUsercontrol上で表示させたいと考えております。
このとき、Prismフレームワークに乗っかった実装ではないと認識しておりますが、いろいろ試行錯誤で試してみて一番自分がやりやすいと感じた実装法がUsercontrolにプロパティを用意するということでした。
ですが、DependencyProperty.Registerを行うにあたり「PropertyChangedCallback」を定義したのですがWindow側で設定する値が定数でなければ呼ばれない状況です。
Bindingした動的な値もこのPropertyChangedCallbackが呼ばれるようにするためにはどうしたら良いでしょうか?
試しに、TextBlockやLabelで動的に配置したところBindingした動的な値を表示させられたので実装可能と認識しております。
発生している問題・エラーメッセージ
ActionPanelViewModel のオブジェクトに No プロパティが見つかりません。
該当のソースコード
[WindowのXaml]
Xaml
1< !-- 省略 -- 2 Height="360" Width="500" 3 prism:ViewModelLocator.AutoWireViewModel="True"> 4 <Window.Resources> 5 <local:TestViewModel x:Key="ViewModel"/> 6 </Window.Resources> 7 <Grid DataContext="{StaticResource ViewModel}"> 8 <Grid.ColumnDefinitions> 9 <ColumnDefinition Width="7*"/> 10 <ColumnDefinition Width="2*"/> 11 </Grid.ColumnDefinitions> 12 <Label Grid.Column="0" Content="承認フロー名:" Margin="0,0,300,295"/> 13 <TextBox Grid.Column="0" Margin="0,0,130,295" HorizontalAlignment="Right" Width="164" /> 14 <ItemsControl Grid.Column="0" ItemsSource="{Binding Items}" Margin="0,42,0,0.5"> 15 <ItemsControl.ItemsPanel> 16 <ItemsPanelTemplate> 17 <Canvas /> 18 </ItemsPanelTemplate> 19 </ItemsControl.ItemsPanel> 20 <ItemsControl.ItemTemplate> 21 <DataTemplate DataType="local:Item"> 22 <views:ActionPanel No="{Binding No}"/> 23 <!-- Label Content="{Binding No}"/ --> 24 </DataTemplate> 25 </ItemsControl.ItemTemplate> 26 <ItemsControl.ItemContainerStyle> 27 <Style TargetType="ContentPresenter"> 28 <Setter Property="Canvas.Top" Value="{Binding Y}" /> 29 <Setter Property="Canvas.Left" Value="{Binding X}" /> 30 </Style> 31 </ItemsControl.ItemContainerStyle> 32 </ItemsControl> 33 <Button Content="追加" Command="{Binding AddCommand}" Grid.Column="1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="90" Height="35"/> 34 <Button Content="削除" Command="{Binding DelCommand}" Grid.Column="1" HorizontalAlignment="Left" Margin="10,68,0,0" VerticalAlignment="Top" Width="90" Height="35"/> 35 </Grid> 36</Window>
[windowのViewModel]
C#
1public class TestViewModel : BindableBase, INotifyPropertyChanged 2 { 3 //フィールド 4 private static int _xCode=5; 5 private int _yCode; 6 private int _no; 7 Stack<Item> _stack; 8 9 public TestViewModel() 10 { 11 _no = 0; 12 _yCode = 5; 13 _items = new ObservableCollection<Item>(); 14 _stack = new Stack<Item>(); 15 AddCommand = new DelegateCommand(ExecuteAddCommand); 16 DelCommand = new DelegateCommand(ExecuteDelCommand); 17 } 18 19 public string No 20 { 21 get { return _no.ToString(); } 22 } 23 24 25 private ObservableCollection<Item> _items; 26 public ObservableCollection<Item> Items 27 { 28 get { return _items; } 29 } 30 31 private DelegateCommand _addCommand; 32 public DelegateCommand AddCommand { get; } 33 34 private void ExecuteAddCommand() 35 { 36 _no++; 37 Item itm = new Item(_no.ToString(), _xCode, _yCode); 38 _stack.Push(itm); 39 _items.Add(itm); 40 _yCode += 60; 41 } 42 43 private DelegateCommand _delCommand; 44 public DelegateCommand DelCommand { get; } 45 46 private void ExecuteDelCommand() 47 { 48 if (_no > 0) 49 { 50 Item itm = _stack.Pop(); 51 _items.Remove(itm); 52 _yCode -= 60; 53 _no--; 54 } 55 else 56 { 57 MessageBox.Show("これ以上削除できません。"); 58 } 59 } 60 } 61 62 public class Item 63 { 64 public Item(string no, int x, int y) 65 { 66 No = no; 67 X = x; 68 Y = y; 69 } 70 public String No { get; set; } 71 public int X { get; set; } 72 public int Y { get; set; } 73 }
[UserControlのXaml]
Xaml
1< !-- 省略 -- 2 Width="340" Height="60" 3 x:Name="panel" 4 prism:ViewModelLocator.AutoWireViewModel="True"> 5 <Grid > 6 <TextBlock Text="{Binding No, ElementName=panel}" Margin="2,2,313,35" FontSize="14"/> 7 <!--以下は本ユーザコントロールのViewModelにてバインドし表示--> 8 <ComboBox ItemsSource="{Binding People}" SelectedValue="Value" DisplayMemberPath="DisplayValue" 9 SelectedItem="{Binding SelectedAuthority,Mode=TwoWay}" HorizontalAlignment="Left" Height="25" VerticalAlignment="Top" Width="173" Margin="27,0,0,0"/> 10 <ComboBox ItemsSource="{Binding Authority}" SelectedValue="Value" DisplayMemberPath="DisplayValue" 11 SelectedItem="{Binding SelectedAuthority,Mode=TwoWay}" HorizontalAlignment="Left" Margin="210,0,0,0" VerticalAlignment="Top" Width="130" Height="25"/> 12 <Label Content="{Binding Indicator}" HorizontalAlignment="Left" Margin="0,30,0,0" VerticalAlignment="Top" Width="80" Height="30" FontSize="14" FontWeight="Bold" FontFamily="Yu Gothic UI Semibold"/> 13 </Grid> 14</UserControl>
[UserControlのクラスコード]
C#
1 public partial class ActionPanel : UserControl 2 { 3 public string No 4 { 5 get { return (string)this.GetValue(ActionPanel.NoProperty); } 6 set { this.SetValue(ActionPanel.NoProperty, value); } 7 } 8 9 public ActionPanel() 10 { 11 InitializeComponent(); 12 } 13 14 15 public static readonly DependencyProperty NoProperty = DependencyProperty.Register( 16 "No",typeof(string),typeof(ActionPanel), 17 new FrameworkPropertyMetadata("No", new PropertyChangedCallback(OnNoChanged))); 18 19 private static void OnNoChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 20 { 21 ActionPanel ctl = d as ActionPanel; //null checks omitted 22 string s = e.NewValue as string; //null checks omitted 23 if(ctl== null || s == string.Empty) 24 { 25 ctl.No = ""; 26 } 27 else 28 { 29 ctl.No = s; 30 } 31 } 32 }
試したこと
上述に記載した通り、TextBlockやLabelではBindingした値が動的に設定され、動的に配置したコントロール上に表示されますが、自作のユーザコントロールでは実現できていない状況です。
どうすれば実現できるかご教授いただけますと幸いです。
補足情報(FW/ツールのバージョンなど)
※上述のWindowはMainWindowのメニューにあるボタンを押下して表示するものです。
なので、「RegionManager」は使用できないと認識しております。
また、動的に配置したユーザコントロール上で設定される情報をWindow側で管理できるような実装をしたいと考えておりますが、これについてもご教授いただける手法がございましたら教えていただけますと幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/04/19 12:18
2021/04/19 12:35
2021/04/19 14:36