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

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

新規登録して質問してみよう
ただいま回答率
85.48%
XAML

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

WPF

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

Q&A

解決済

1回答

2355閲覧

Gridパネルにマス目状に配置したItemの共通化

Hayashi_Jelly

総合スコア26

XAML

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

WPF

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

1グッド

0クリップ

投稿2021/02/23 04:01

すみません。調べれば簡単にできるかとお持っていたのですが、WPFが全く分からず困っております。

困っていること

  • github の芝生のようなものを作りました。下記ソースの各セル(Labelコントロール)は、日あたりの指針を色で表示するための要素ですが、

年間分366個記述しました。
これを共通化したいのですが、うまくいかず困っています。

xaml

1<Grid> 2 <Grid.RowDefinitions> 3 <RowDefinition Height="18" /> 4 : 5 <RowDefinition Height="18" /> 6 </Grid.RowDefinitions> 7 <Grid.ColumnDefinitions> 8 <ColumnDefinition Width="18" /> 9 : 10 <ColumnDefinition Width="18" /> 11 </Grid.ColumnDefinitions> 12 <Label Grid.Row="1" Grid.Column="1"> 13 <Label.Background> 14 <SolidColorBrush Color="{Binding Range[0].Density, Converter={StaticResource DensityToGreenConverter}}" /> 15 </Label.Background> 16 </Label> 17 : 18 <Label Grid.Row="3" Grid.Column="53" > 19 <Label.Background> 20 <SolidColorBrush Color="{Binding Range[366].Density, Converter={StaticResource DensityToGreenConverter}}" /> 21 </Label.Background> 22 </Label> 23</Grid>

実現したいこと

  1. Listboxのようなもので、Lableコントロールを共通化できないか?
  2. あるいは、Labelの内容を1行で記述できるようできないか?

2.は共通化とは少し違うのですが、エディタの編集が楽になるので、それでもいいかな思っています。

###やってみたこと

  • ListBoxListViewで、ItemPanelTemplateGridパネルにして、共通化してみる。

ネットの情報によると、Grid.RowGrid.Columnは効かないらしい・・・

xaml

1<ListView ItemsSource="{Binding Range}"> 2 <ListView.ItemsPanel> 3 <ItemsPanelTemplate> 4 <Grid> 5 <Grid.RowDefinitions> 6 <RowDefinition Height="18" /> 7 : 8 <RowDefinition Height="18" /> 9 </Grid.RowDefinitions> 10 <Grid.ColumnDefinitions> 11 <ColumnDefinition Width="18" /> 12 : 13 <ColumnDefinition Width="18" /> 14 </Grid.ColumnDefinitions> 15 </Grid> 16 </ItemsPanelTemplate> 17 </ListView.ItemsPanel> 18 <ListView.ItemTemplate> 19 <DataTemplate> 20 <Label Grid.Row="{Binding Row}" Grid.Column="{Binding Column}"> 21 <Label.Background> 22 <SolidColorBrush Color="{Binding Density, Converter={StaticResource DensityToGreenConverter}}" /> 23 </Label.Background> 24 </Label> 25 </DataTemplate> 26 </ListView.ItemTemplate> 27</ListView>
  • ControlTemplateでワンライナーにできないか・・・

Range[x].DensityLabelBackgroundプロパティへのバインド方法が、SolidColorBrushColorに対してバインドする方法しかわからないため、1行にできない・・・(下記ソースは、LableにはColorプロパティはないので、実行前エラーになる)

xaml

1 <ControlTemplate x:Key="GreenCell" TargetType="Label"> 2 <Label> 3 <Label.Background> 4 <SolidColorBrush Color="{TemplateBinding Color, Converter={StaticResource DensityToGreenConverter}}" /> 5 </Label.Background> 6 </Label> 7 </ControlTemplate> 8 : 9 <Label Grid.Row="1" Grid.Column="1" Template={StaticResource GreenCell}" Color="{Binding Range[0].Density}" />
TN8001👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

Listboxのようなもので、Lableコントロールを共通化できないか?

コレクションをバインドできるListBox等を見ると、継承の祖先にItemsControlがあることがわかります(選択がなく単に一覧表示したいような場合に最適です)
ListBox クラス (System.Windows.Controls) | Microsoft Docs
ItemsControl クラス (System.Windows.Controls) | Microsoft Docs

カスタマイズに関してはこちらが詳しいです。
ItemsControl 攻略 ~ 外観のカスタマイズ | grabacr.nét

グリッド内の個々のアイテムが同サイズの場合は、UniformGridが便利です。
UniformGrid クラス (System.Windows.Controls.Primitives) | Microsoft Docs

しかし並べ方が左右方向にしかできないので「GitHub Contribution Graph」のように上下方向にしたい場合は、↓がいいんじゃないでしょうか(ざっと試したところ期待通りの動きです)
Layout orientation of UniformGrid


上記で目的は達成だと思いますが、誤解があるようなので残りの問題も片づけます。

ネットの情報によると、Grid.Row、Grid.Columnは効かないらしい・・・

どちらをご覧になったのかわかりませんが、そんなことないですよ。
「ライブ ビジュアル ツリー」で見るとわかりますがContentPresenterが挟まるため、ItemContainerStyleで当てる必要があるのが注意点です。

デバッグ中に XAML のプロパティを調べる - Visual Studio | Microsoft Docs
ItemsControl.ItemContainerStyle プロパティ (System.Windows.Controls) | Microsoft Docs

Labelの内容を1行で記述できるようできないか?

DensityToGreenConverterが、ColorでなくBrushを返せばいいのでは?


xml

1<Window 2 x:Class="Questions324177.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:Questions324177" 6 Width="800" 7 Height="450"> 8 <StackPanel> 9 <GroupBox Header="UniformGrid"> 10 <ItemsControl HorizontalAlignment="Left" ItemsSource="{Binding Items}"> 11 <ItemsControl.ItemsPanel> 12 <ItemsPanelTemplate> 13 <UniformGrid Rows="7" /> 14 <!--<local:UniformGridWithOrientation Rows="7" />--> 15 </ItemsPanelTemplate> 16 </ItemsControl.ItemsPanel> 17 <ItemsControl.ItemTemplate> 18 <DataTemplate> 19 <Border 20 x:Name="border" 21 Width="10" 22 Height="10" 23 Margin="2" 24 Background="#FFEBEDF0" 25 CornerRadius="2" /> 26 <DataTemplate.Triggers> 27 <DataTrigger Binding="{Binding}" Value="1"> 28 <Setter TargetName="border" Property="Background" Value="#FF9BE9A8" /> 29 </DataTrigger> 30 <DataTrigger Binding="{Binding}" Value="2"> 31 <Setter TargetName="border" Property="Background" Value="#FF40C463" /> 32 </DataTrigger> 33 <DataTrigger Binding="{Binding}" Value="3"> 34 <Setter TargetName="border" Property="Background" Value="#FF30A14E" /> 35 </DataTrigger> 36 <DataTrigger Binding="{Binding}" Value="4"> 37 <Setter TargetName="border" Property="Background" Value="#FF216E39" /> 38 </DataTrigger> 39 </DataTemplate.Triggers> 40 </DataTemplate> 41 </ItemsControl.ItemTemplate> 42 </ItemsControl> 43 </GroupBox> 44 45 <GroupBox Header="Grid Row Column Binding"> 46 <ItemsControl HorizontalAlignment="Left" ItemsSource="{Binding Range}"> 47 <ItemsControl.ItemsPanel> 48 <ItemsPanelTemplate> 49 <Grid> 50 <Grid.ColumnDefinitions> 51 <ColumnDefinition /> 52 <ColumnDefinition /> 53 <ColumnDefinition /> 54 <ColumnDefinition /> 55 <ColumnDefinition /> 56 <ColumnDefinition /> 57 <ColumnDefinition /> 58 <ColumnDefinition /> 59 <ColumnDefinition /> 60 <ColumnDefinition /> 61 <ColumnDefinition /> 62 <ColumnDefinition /> 63 <ColumnDefinition /> 64 <ColumnDefinition /> 65 <ColumnDefinition /> 66 <ColumnDefinition /> 67 <ColumnDefinition /> 68 <ColumnDefinition /> 69 <ColumnDefinition /> 70 <ColumnDefinition /> 71 <ColumnDefinition /> 72 <ColumnDefinition /> 73 <ColumnDefinition /> 74 <ColumnDefinition /> 75 <ColumnDefinition /> 76 <ColumnDefinition /> 77 <ColumnDefinition /> 78 <ColumnDefinition /> 79 <ColumnDefinition /> 80 <ColumnDefinition /> 81 <ColumnDefinition /> 82 <ColumnDefinition /> 83 <ColumnDefinition /> 84 <ColumnDefinition /> 85 <ColumnDefinition /> 86 <ColumnDefinition /> 87 <ColumnDefinition /> 88 <ColumnDefinition /> 89 <ColumnDefinition /> 90 <ColumnDefinition /> 91 <ColumnDefinition /> 92 <ColumnDefinition /> 93 <ColumnDefinition /> 94 <ColumnDefinition /> 95 <ColumnDefinition /> 96 <ColumnDefinition /> 97 <ColumnDefinition /> 98 <ColumnDefinition /> 99 <ColumnDefinition /> 100 <ColumnDefinition /> 101 <ColumnDefinition /> 102 <ColumnDefinition /> 103 <ColumnDefinition /> 104 </Grid.ColumnDefinitions> 105 <Grid.RowDefinitions> 106 <RowDefinition /> 107 <RowDefinition /> 108 <RowDefinition /> 109 <RowDefinition /> 110 <RowDefinition /> 111 <RowDefinition /> 112 <RowDefinition /> 113 </Grid.RowDefinitions> 114 </Grid> 115 </ItemsPanelTemplate> 116 </ItemsControl.ItemsPanel> 117 <ItemsControl.ItemContainerStyle> 118 <Style> 119 <Setter Property="Grid.Column" Value="{Binding Column}" /> 120 <Setter Property="Grid.Row" Value="{Binding Row}" /> 121 </Style> 122 </ItemsControl.ItemContainerStyle> 123 <ItemsControl.ItemTemplate> 124 <DataTemplate> 125 <DataTemplate.Resources> 126 <local:DensityToGreenConverter x:Key="DensityToGreenConverter" /> 127 </DataTemplate.Resources> 128 <Border 129 Width="10" 130 Height="10" 131 Margin="2" 132 Background="{Binding Density, Converter={StaticResource DensityToGreenConverter}}" 133 CornerRadius="2" /> 134 </DataTemplate> 135 </ItemsControl.ItemTemplate> 136 </ItemsControl> 137 </GroupBox> 138 </StackPanel> 139</Window>

cs

1using System; 2using System.Globalization; 3using System.Linq; 4using System.Windows; 5using System.Windows.Controls; 6using System.Windows.Controls.Primitives; 7using System.Windows.Data; 8using System.Windows.Media; 9 10namespace Questions324177 11{ 12 public partial class MainWindow : Window 13 { 14 public int[] Items { get; } 15 public Range[] Range { get; } 16 17 public MainWindow() 18 { 19 InitializeComponent(); 20 DataContext = this; 21 22 var r = new Random(); 23 Items = Enumerable.Range(0, 366) 24 .Select(x => r.Next(5)) 25 .ToArray(); 26 Range = Items.Select((v, i) => new Range { Column = i / 7, Row = i % 7, Density = v }) 27 .ToArray(); 28 } 29 } 30 31 public class Range 32 { 33 public int Column { get; set; } 34 public int Row { get; set; } 35 public int Density { get; set; } 36 } 37 38 public class DensityToGreenConverter : IValueConverter // 雑すぎw 39 { 40 private static readonly Brush[] brushes; 41 static DensityToGreenConverter() 42 { 43 var c = new BrushConverter(); 44 brushes = new Brush[] 45 { 46 (Brush) c.ConvertFrom("#FFEBEDF0"), 47 (Brush) c.ConvertFrom("#FF9BE9A8"), 48 (Brush) c.ConvertFrom("#FF40C463"), 49 (Brush) c.ConvertFrom("#FF30A14E"), 50 (Brush) c.ConvertFrom("#FF216E39"), 51 }; 52 } 53 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => brushes[(int)value]; 54 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); 55 } 56 57 // 長くなるので省略するが、上下方向に並べたい場合こちらを使用 58 // [Layout orientation of UniformGrid](https://social.msdn.microsoft.com/Forums/en-US/104b9cb8-3e1a-4e2e-ac62-4f9b32cc21f0/layout-orientation-of-uniformgrid?forum=wpf) 59 //public class UniformGridWithOrientation : UniformGrid { } 60}

アプリ画像

注)元データは同じだが方向が違う。合わせるにはUniformGridの代わりにUniformGridWithOrientationを使用すること。

投稿2021/02/23 09:51

編集2023/07/26 14:12
TN8001

総合スコア9321

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

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

Hayashi_Jelly

2021/02/24 23:16

ありがとうございました。出来ました。 サイトを参考にさせていただきました。 Grid.Row, Grid.Columnが効かないというのは、 「Gridは子要素を順番に並べる機能を持たない」という表現を誤解していました。 ItemTemplate内で指定した場合は期待通りに動かなかいのは何故なのか、なんとなく理解できた気がします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問