メインウィンドウのリストボックスアイテムをダブルクリックすると、テキストブロックにバインディングしてる値を取得してサブウィンドウに表示したいです。
データバインディングを勉強されたのですね。前回よりだいぶ進んでいるようですね^^
ダブルクリックしたアイテムをToStringメソッドでstr変数に入れてサブウィンドウに入れようと思った
何をバインディングしているかが不明ですが、listBox.SelectedItem
自体は個々のアイテム(check
やtextArray
プロパティがあるクラス)になっています。
しかしSelectedItem
はobject
のためキャストが必要です。
Selector.SelectedItem プロパティ (System.Windows.Controls.Primitives) | Microsoft Docs
例えばこのような
cs
1var item = listBox.SelectedItem as ToDoItem;
2var str = item?.Text;
しかしListBox
自体のMouseDoubleClick
ですと、何もない部分も反応してしまってあまり使い勝手がよくないです。
ListBoxItem
にMouseDoubleClick
を付けるほうがおすすめです。
サブウィンドウに表示するときもせっかくなのでバインディングしましょう。
表示と言っていますが、実際は編集でしょうか?
表示だけならいらないのですが、編集するとなるとINotifyPropertyChanged
を実装する必要があります(WPFでは最重要インターフェースです)
回答では↓を使用しました。
NuGet Gallery | CommunityToolkit.Mvvm 7.0.3
ObservableObject - Windows Community Toolkit | Microsoft Docs
MainWindow
xml
1<Window
2 x:Class="Questions368346.MainWindow"
3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 Title="MainWindow"
6 Width="800"
7 Height="450">
8 <Grid>
9 <Grid.RowDefinitions>
10 <RowDefinition Height="Auto" />
11 <RowDefinition />
12 </Grid.RowDefinitions>
13 <!-- 編集 こうしないのであればIsSynchronizedWithCurrentItemは不要 -->
14 <TextBox Margin="5" Text="{Binding /Text, UpdateSourceTrigger=PropertyChanged}" />
15
16 <ListBox
17 x:Name="listBox"
18 Grid.Row="1"
19 Margin="5"
20 Background="WhiteSmoke"
21 IsSynchronizedWithCurrentItem="True"
22 ItemsSource="{Binding}"
23 SelectionMode="Single">
24 <ListBox.ItemContainerStyle>
25 <Style TargetType="ListBoxItem">
26 <EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick" />
27 </Style>
28 </ListBox.ItemContainerStyle>
29 <ListBox.ItemTemplate>
30 <DataTemplate>
31 <StackPanel Orientation="Horizontal">
32 <CheckBox VerticalContentAlignment="Center" IsChecked="{Binding Check}" />
33 <TextBlock Text="{Binding Text}" />
34 </StackPanel>
35 </DataTemplate>
36 </ListBox.ItemTemplate>
37 </ListBox>
38 </Grid>
39</Window>
cs
1using System.Collections.ObjectModel;
2using System.Windows;
3using System.Windows.Controls;
4using System.Windows.Input;
5using CommunityToolkit.Mvvm.ComponentModel;
6
7namespace Questions368346
8{
9 class ToDoItem : ObservableObject
10 {
11 public string Text { get => _Text; set => SetProperty(ref _Text, value); }
12 private string _Text;
13
14 public bool Check { get => _Check; set => SetProperty(ref _Check, value); }
15 private bool _Check;
16 }
17
18 public partial class MainWindow : Window
19 {
20 public MainWindow()
21 {
22 InitializeComponent();
23
24 DataContext = new ObservableCollection<ToDoItem>
25 {
26 new ToDoItem { Text = "aaa", },
27 new ToDoItem { Text = "bbb", },
28 new ToDoItem { Text = "ccc", },
29 };
30 }
31
32 private void ListBoxItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
33 {
34 if (sender is ListBoxItem listBoxItem)
35 {
36 if (listBoxItem.DataContext is ToDoItem item)
37 {
38 var win1 = new Window1
39 {
40 Owner = this,
41 // DataContextの個々のアイテムをセット
42 // Window1でも <TextBox Text="{Binding Text}" /> のようにバインディングできる
43 DataContext = item,
44 };
45
46 win1.addButton.Visibility = Visibility.Collapsed;
47 win1.canButton.Visibility = Visibility.Collapsed;
48 win1.okButton.Visibility = Visibility.Visible;
49
50 // その場で書き換えてしまうので、もし編集のキャンセルが必要な場合はひと工夫必要
51 win1.ShowDialog();
52 }
53 }
54 }
55 }
56}
SubWindow
xml
1<Window
2 x:Class="Questions368346.Window1"
3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 Title="SubWindow"
6 Width="400"
7 FocusManager.FocusedElement="{Binding ElementName=mainText}"
8 SizeToContent="Height"
9 WindowStartupLocation="CenterOwner">
10 <StackPanel Margin="5">
11 <TextBox x:Name="mainText" Margin="5,0" Text="{Binding Text}" />
12
13 <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
14 <StackPanel.Resources>
15 <Style TargetType="Button">
16 <Setter Property="MinWidth" Value="80" />
17 <Setter Property="Margin" Value="5" />
18 </Style>
19 </StackPanel.Resources>
20 <Button x:Name="addButton" Content="追加" />
21 <Button x:Name="okButton" Content="OK" IsDefault="True" Click="OkButton_Click" />
22 <Button x:Name="canButton" Content="キャンセル" IsCancel="True" />
23 </StackPanel>
24 </StackPanel>
25</Window>
cs
1using System.Windows;
2
3namespace Questions368346
4{
5 public partial class Window1 : Window
6 {
7 public Window1() => InitializeComponent();
8
9 private void OkButton_Click(object sender, RoutedEventArgs e)
10 => DialogResult = true;
11 }
12}
個人的にはダイアログをポンポン出すのは趣味でないので、編集なら同じウィンドウ内でやりたいですね。
編集だけなら非常に簡単にできます。
マスターと詳細のバインディング シナリオ - WPF .NET | Microsoft Docs
とはいえ追加が絡むとなると、また話が変わってくるのですが^^;
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/09 12:37