🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

WPF

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

Q&A

解決済

1回答

2201閲覧

Wpf 動的に作成したボタンの処理方法

kota190

総合スコア3

C#

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

WPF

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

1グッド

0クリップ

投稿2020/12/20 09:56

編集2020/12/20 13:25

前提・実現したいこと

Wpfの画面で、Excelのように行列が固定(ウィンドウ枠の固定のような動作)でスクロール可能な画面の構築をしようとしています。
縦方向に店舗、横方向に売り上げがあり、折れ線グラフを表示したいと思ってます。

店舗名のボタンを押すと、次の店舗名との間に詳細のウィンドウを開閉させたいです。

今回、書籍やネットなどをみて、ItemsControlを使用して、縦の店舗名とボタンを配置するところまでは
行ったのですが、ボタンを押したとき、押した店舗のみの詳細(DetailNm、Detail)を開く方法を知りたいです。
※縦の店舗やボタンは条件により変動するため、固定にはできないのです。

ただいま勉強中のため、そもそも使用するタグを見直した方が良いなどもあれば、
アドバイスいただきたいです。

該当のソースコード

Wpf

1<Grid x:Name="Grid0"> 2<Grid.RowDefinitions> 3 <RowDefinition Height="50"/> 4 <RowDefinition Height="*"/> 5 <RowDefinition Height="25"/> 6</Grid.RowDefinitions> 7<Grid.ColumnDefinitions> 8 <ColumnDefinition Width="150"/> 9 <ColumnDefinition Width="*"/> 10 <ColumnDefinition Width="18"/> 11</Grid.ColumnDefinitions> 12 13<ScrollViewer x:Name="YokoSenViewer" Padding="0" Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" 14 ScrollViewer.HorizontalScrollBarVisibility="Visible" 15 ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollChanged="Yoko_Scroll"> 16 <Border x:Name="YokoSen" Background="Transparent" BorderBrush="Transparent" BorderThickness="2,0,2,0" > 17 <StackPanel x:Name="YokoSenPanel" Orientation="Vertical"/> 18 </Border> 19</ScrollViewer> 20 21<ScrollViewer x:Name="AreaNmViewer" Padding="0" Grid.Column="0" Grid.Row="1" 22 ScrollViewer.HorizontalScrollBarVisibility="Disabled" 23 ScrollViewer.VerticalScrollBarVisibility="Hidden"> 24 <Canvas x:Name="AreaNmPanel" VerticalAlignment="Top"> 25 <ItemsControl x:Name="Test2" ItemsSource="{Binding AreaList}"> 26 <ItemsControl.ItemTemplate> 27 <DataTemplate> 28 <StackPanel Orientation="Vertical"> 29 <StackPanel Orientation="Horizontal" Height="30" Width="150" Margin="0"> 30 <Label x:Name="AreaName" Content="{Binding TenpoMei}"/> 31 <Button Padding="0" Content="詳細" Name="BtnDetail" Visibility="{Binding IsDetail}" Click="BtnDetail_Click"/> 32 </StackPanel> 33 <Canvas x:Name="DetailNm" Height="0" Margin="0,0,0,0" Background="AliceBlue"/> 34 </StackPanel> 35 </DataTemplate> 36 </ItemsControl.ItemTemplate> 37 </ItemsControl> 38 </Canvas> 39</ScrollViewer> 40 41<ScrollViewer x:Name="AreaSenViewer" Padding="0" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" 42 ScrollViewer.HorizontalScrollBarVisibility="Disabled" 43 ScrollViewer.VerticalScrollBarVisibility="Visible" 44 ScrollChanged="Tate_Scroll"> 45 <Canvas x:Name="Oresen" VerticalAlignment="Top"> 46 <ItemsControl x:Name="Test" ItemsSource="{Binding AreaList}"> 47 <ItemsControl.ItemTemplate> 48 <DataTemplate> 49 <StackPanel Orientation="Vertical"> 50 <StackPanel Orientation="Horizontal" Height="30" Width="1900" Margin="0"> 51 <canvas x:Name="Area"></canvas> 52 </StackPanel> 53 <Canvas x:Name="Detail" Height="10" Margin="0,0,0,0" Background="AliceBlue"></Canvas> 54 </StackPanel> 55 </DataTemplate> 56 </ItemsControl.ItemTemplate> 57 </ItemsControl> 58 59 </Canvas> 60</ScrollViewer> 61 62<ScrollViewer x:Name="TenpoUriageViewer" Grid.Column="1" Grid.Row="1" 63 ScrollViewer.HorizontalScrollBarVisibility="Hidden" 64 ScrollViewer.VerticalScrollBarVisibility="Hidden" PreviewMouseWheel="_MouseWheelScroll"> 65<Border BorderBrush="#99DDCC" BorderThickness="2"> 66 <Grid x:Name="UriageSenGrid" Background="Transparent"> 67 <Canvas x:Name="tenpoUriagePanel" PreviewMouseLeftButtonDown="tenpoUriagePanel_click"> 68 </Canvas> 69 </Grid> 70</Border> 71</ScrollViewer> 72 73</Grid> 74 75</Grid>

イメージ説明

補足情報(FW/ツールのバージョンなど)

C# VisualStudio2010

TN8001👍を押しています

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

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

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

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

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

TN8001

2020/12/20 11:00

kota190さん >Wpfの画面で、Excelのように行列が固定でスクロール可能な画面の構築をしようとしています。 >縦方向に店舗、横方向に売り上げがあり、折れ線グラフを表示したいと思ってます。 縦軸が店舗で横軸が売り上げ等のデータはわかりますが、グラフというのはどういうことですか? 詳細のウィンドウにグラフがあるという意味ですか? >ボタンを押したとき、押した店舗のみの詳細(DetailNm、Detail)を開く方法を知りたいです。 Canvas x:Name="DetailNm"とCanvas x:Name="Detail"のことだと思いますが、中身はもう入っているということでしょうか? ScrollViewer がいっぱいありしかも重なっていますが、一体どういう関係なんでしょうか? 完成イメージを簡単な図で出していただいたほうがいい気がします。
kota190

2020/12/20 11:35

TN8001さん 質問を見ていただきありがとうございます。 >縦軸が店舗で横軸が売り上げ等のデータはわかりますが、グラフというのはどういうことですか? >詳細のウィンドウにグラフがあるという意味ですか? 店舗単位の折れ線グラフも表示するのですが、 ボタンを開くと、商品アイテムごとの折れ線が出るイメージです。 >Canvas x:Name="DetailNm"とCanvas x:Name="Detail"のことだと思いますが、中身はもう入っているということでしょうか? ボタンを押したときに最新の中身を表示したいです。 >ScrollViewer がいっぱいありしかも重なっていますが、一体どういう関係なんでしょうか? 縦の店舗でもスクロールが発生し、横の売り上げでもスクロールが発生するため、 Excelのように行、列ヘッダの固定のように動作させたいため、ScrollViewerを重ねました。 YokoSenViewerのスクロールバーを移動すると、TenpoUriageViewerが横スクロールし、 AreaSenViewerのスクロールバーを縦に移動すると、TenpoUriageViewerが同期して縦にスクロールするイメージです。 縦・横固定スクロールを実現するために考えたのものですが、通常はこのような作りにしないなどのことがあれば、教えていただきたいです。 >完成イメージを簡単な図で出していただいたほうがいい気がします。 初めて投稿するため、完成イメージ図の出し方がわからず、これからヘルプなどをみて 投稿できるかやってみます。
kota190

2020/12/20 13:26

TN8001さん 画像の貼り方の情報ありがとうございました。
guest

回答1

0

ベストアンサー

グラフをそのように表示するんですか。。。
通常折れ線グラフの横軸(今回は縦ですが)は時系列等の推移を見るもので、この例には向いていないように思います。
しかし別質問もありますし、それは置いておきます。

現状ある程度動いているのであれば、↓のような感じで開閉はできると思います。

xml

1<Canvas x:Name="DetailNm" Visibility="{Binding IsDetail}" /> 2<Canvas x:Name="Detail" Visibility="{Binding IsDetail}" /> 3 4 <!-- IsDetailがboolなら 5<Canvas x:Name="DetailNm" Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}}" /> 6<Canvas x:Name="Detail" Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}}"/> 7-->

cs

1private void BtnDetail_Click(object sender, RoutedEventArgs e) 2{ 3 if ((sender as Button)?.DataContext is Area area) 4 { 5 foreach (var a in AreaList) a.IsDetail = false; 6 area.IsDetail = true; 7 } 8}

RadioButtonを使えばコードビハインドいらずですみますが、すべて閉じることができなくなるので一長一短ですね。


この表示にこだわる場合は使えるかどうかちょっとわかりませんが、DataGridの行の詳細やグループ化で畳むような表現はあります。

方法: DataGrid コントロールに行の詳細を追加する - WPF .NET Framework | Microsoft Docs

方法: DataGrid コントロールでデータをグループ化、並べ替え、およびフィルター処理する - WPF .NET Framework | Microsoft Docs


xml

1<Window 2 x:Class="Questions311409.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450"> 7 <Window.Resources> 8 <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 9 <Style 10 x:Key="ButtonStyle" 11 BasedOn="{StaticResource {x:Type ToggleButton}}" 12 TargetType="{x:Type RadioButton}" /> 13 </Window.Resources> 14 15 <Border 16 Margin="5" 17 Background="LightGray" 18 BorderBrush="Black" 19 BorderThickness="1"> 20 <Grid> 21 <Grid.RowDefinitions> 22 <RowDefinition Height="50" /> 23 <RowDefinition Height="*" /> 24 <RowDefinition Height="Auto" /> 25 </Grid.RowDefinitions> 26 <Grid.ColumnDefinitions> 27 <ColumnDefinition Width="Auto" /> 28 <ColumnDefinition Width="*" /> 29 </Grid.ColumnDefinitions> 30 31 <ScrollViewer 32 x:Name="ColumnHeader" 33 Grid.Column="1" 34 ScrollViewer.HorizontalScrollBarVisibility="Hidden" 35 ScrollViewer.VerticalScrollBarVisibility="Hidden"> 36 <Border BorderBrush="DimGray" BorderThickness="1"> 37 <StackPanel x:Name="YokoSenPanel" Orientation="Vertical" /> 38 </Border> 39 </ScrollViewer> 40 41 <ScrollViewer 42 x:Name="RowHeader" 43 Grid.Row="1" 44 ScrollChanged="ScrollChanged" 45 ScrollViewer.HorizontalScrollBarVisibility="Hidden" 46 ScrollViewer.VerticalScrollBarVisibility="Hidden"> 47 <ItemsControl x:Name="Test2" ItemsSource="{Binding AreaList}"> 48 <ItemsControl.ItemTemplate> 49 <DataTemplate> 50 <Border 51 Padding="5" 52 BorderBrush="DimGray" 53 BorderThickness="1"> 54 <StackPanel> 55 <StackPanel Orientation="Horizontal"> 56 <Label x:Name="AreaName" Content="{Binding TenpoMei}" /> 57 <RadioButton 58 Content="詳細" 59 GroupName="Area" 60 IsChecked="{Binding IsDetail}" 61 Style="{StaticResource ButtonStyle}" /> 62 </StackPanel> 63 <ItemsControl 64 Margin="20,0,0,0" 65 ItemsSource="{Binding Items}" 66 Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}}"> 67 <ItemsControl.ItemTemplate> 68 <DataTemplate> 69 <TextBlock Text="{Binding ShouhinMei}" /> 70 </DataTemplate> 71 </ItemsControl.ItemTemplate> 72 </ItemsControl> 73 </StackPanel> 74 </Border> 75 </DataTemplate> 76 </ItemsControl.ItemTemplate> 77 </ItemsControl> 78 </ScrollViewer> 79 80 <ScrollViewer 81 x:Name="AreaSenViewer" 82 Grid.Row="1" 83 Grid.RowSpan="2" 84 Grid.Column="1" 85 Background="White" 86 ScrollChanged="ScrollChanged" 87 ScrollViewer.HorizontalScrollBarVisibility="Auto" 88 ScrollViewer.VerticalScrollBarVisibility="Visible"> 89 <ItemsControl 90 x:Name="Test" 91 AlternationCount="2" 92 ItemsSource="{Binding AreaList}"> 93 <ItemsControl.ItemTemplate> 94 <DataTemplate> 95 <Border 96 Padding="5" 97 BorderBrush="DimGray" 98 BorderThickness="1"> 99 <StackPanel HorizontalAlignment="Left"> 100 <Grid> 101 <!-- 高さ合わせ用ダミー --> 102 <Label 103 x:Name="dummy" 104 Content="{Binding TenpoMei}" 105 Visibility="Hidden" /> 106 <Canvas x:Name="Area" Width="{Binding Goukei}"> 107 <Line 108 x:Name="Line" 109 Stroke="SkyBlue" 110 StrokeThickness="10" 111 X2="{Binding Goukei}" 112 Y1="16" 113 Y2="16" /> 114 <TextBlock Text="{Binding Jyuni}" /> 115 </Canvas> 116 </Grid> 117 118 <ItemsControl ItemsSource="{Binding Items}" Visibility="{Binding IsDetail, Converter={StaticResource BooleanToVisibilityConverter}, Mode=OneWay}"> 119 <ItemsControl.ItemTemplate> 120 <DataTemplate> 121 <Grid> 122 <Canvas x:Name="Detail"> 123 <Line 124 HorizontalAlignment="Center" 125 VerticalAlignment="Center" 126 Stroke="YellowGreen" 127 StrokeThickness="10" 128 X2="{Binding Uriage}" 129 Y1="11" 130 Y2="11" /> 131 </Canvas> 132 <TextBlock Text="{Binding Uriage}" /> 133 </Grid> 134 </DataTemplate> 135 </ItemsControl.ItemTemplate> 136 </ItemsControl> 137 </StackPanel> 138 </Border> 139 </DataTemplate> 140 </ItemsControl.ItemTemplate> 141 </ItemsControl> 142 </ScrollViewer> 143 144 <!-- 145 水平スクロールバー表示非表示時の位置合わせ用ダミー 146 微妙に表示タイミングがずれるが、ちゃんとやろうとするとかなり面倒 147 --> 148 <ScrollBar 149 Grid.Row="2" 150 Width="0" 151 Orientation="Horizontal" 152 Visibility="{Binding ComputedHorizontalScrollBarVisibility, ElementName=AreaSenViewer, Mode=OneWay}" /> 153 </Grid> 154 </Border> 155</Window>

cs

1using System.Collections.Generic; 2using System.Collections.ObjectModel; 3using System.ComponentModel; 4using System.Linq; 5using System.Runtime.CompilerServices; 6using System.Windows; 7using System.Windows.Controls; 8 9namespace Questions311409 10{ 11 public class Observable : INotifyPropertyChanged 12 { 13 public event PropertyChangedEventHandler PropertyChanged; 14 protected void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) 15 { 16 if (Equals(storage, value)) return; 17 storage = value; 18 OnPropertyChanged(propertyName); 19 } 20 protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 21 } 22 23 public class Area : Observable 24 { 25 public string TenpoMei { get; } 26 27 public bool IsDetail { get => _IsDetail; set => Set(ref _IsDetail, value); } 28 private bool _IsDetail; 29 30 public string Jyuni { get; } 31 32 public int Goukei => Items.Sum(x => x.Uriage); 33 34 public List<Item> Items { get; } = new List<Item>(); 35 36 37 public Area(string tenpoMei, string jyuni, params Item[] items) 38 { 39 TenpoMei = tenpoMei; 40 Jyuni = jyuni; 41 42 foreach (var item in items) Items.Add(item); 43 } 44 } 45 46 public class Item 47 { 48 public string ShouhinMei { get; } 49 50 public int Uriage { get; } 51 52 public Item(string shouhinMei, int uriage) 53 { 54 ShouhinMei = shouhinMei; 55 Uriage = uriage; 56 } 57 } 58 59 public partial class MainWindow : Window 60 { 61 public ObservableCollection<Area> AreaList { get; } 62 63 public MainWindow() 64 { 65 InitializeComponent(); 66 67 AreaList = new ObservableCollection<Area> 68 { 69 new Area("A店","2位", new Item("商品1", 30), new Item("商品2", 100), new Item("商品3", 70)), 70 new Area("B店","1位", new Item("商品1", 50), new Item("商品2", 150), new Item("商品3", 100)), 71 new Area("C店","3位", new Item("商品1", 10), new Item("商品2", 60), new Item("商品4", 30)), 72 }; 73 74 DataContext = this; 75 } 76 77 private void ScrollChanged(object sender, ScrollChangedEventArgs e) 78 { 79 if (sender == RowHeader) 80 { 81 AreaSenViewer.ScrollToVerticalOffset(e.VerticalOffset); 82 } 83 if (sender == AreaSenViewer) 84 { 85 RowHeader.ScrollToVerticalOffset(e.VerticalOffset); 86 } 87 } 88 89 private void BtnDetail_Click(object sender, RoutedEventArgs e) 90 { 91 if ((sender as Button)?.DataContext is Area area) 92 { 93 foreach (var a in AreaList) a.IsDetail = false; 94 95 area.IsDetail = true; 96 } 97 } 98 } 99}

アプリ画像

投稿2020/12/21 08:54

編集2023/07/25 15:15
TN8001

総合スコア9855

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

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

kota190

2020/12/21 15:54

TN8001さん 回答ありがとうございます。 いただいた回答を元に試してみたいと思います。 結果は後ほど報告したいと思います!
kota190

2021/01/05 15:20

回答が遅くなり申し訳ありません。 いただいた回答を元に試したところ、うまく動作しました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問