トップ回答者
WPF DataGridにバインドしたデータが表示されない

質問
-
WPF DataGridにバインドすると、バインドしたコレクションデータの数だけ行が生成されるのですが、セルに何も表示されず困っています。
1.まず下記のウィンドウがあります。<Window x:Class="KM_Ora.Schedule.View.ScheduleListEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:KM_Ora.Schedule.ViewModel"
xmlns:local2="clr-namespace:KM_Ora.Schedule.Model"
Title="Schedule List Editor" Icon="../../Resources/favicon.ico"
Height="200" Width="640" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0" Name="ScheduleDataGrid" ItemsSource="{Binding ScheduleList}" >
<DataGrid.Columns>
<DataGridTextColumn Header="時刻" Binding="{Binding Date, Mode=TwoWay}" Width="64" />
<DataGridTextColumn Header="分類" Binding="{Binding Title, Mode=TwoWay}" Width="128" />
<DataGridTextColumn Header="スケジュール" Binding="{Binding Title, Mode=TwoWay}" Width="256" />
<DataGridCheckBoxColumn Header="アラーム表示" Binding="{Binding ShowAlarm, Mode=TwoWay}" />
<DataGridCheckBoxColumn Header="Eメール送信" Binding="{Binding SendEMail, Mode=TwoWay}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>2. これにバインドするデータは、以下のクラスです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KM_Ora.Schedule.Model {
internal class Schedule {
private DateTime dateTime;
/// <summary>
/// スケジュールの日時を取得・設定する。
/// </summary>
internal DateTime Datetime {
get { return this.dateTime; }
set { this.dateTime = value; }
}
private string title;
/// <summary>
/// タイトルを取得・設定する。
/// </summary>
internal string Title {
get { return this.title; }
set { this.title = value; }
}
private string scheduleText;
/// <summary>
/// スケジュールを取得・設定する。
/// </summary>
internal string ScheduleText {
get { return this.scheduleText; }
set { this.scheduleText = value; }
}
private bool showAlarm;
/// <summary>
/// アラーム表示するかどうかを取得・設定する。
/// </summary>
internal bool ShowAlarm {
get { return this.showAlarm; }
set { this.showAlarm = value; }
}
private bool sendEMail;
/// <summary>
/// アラームをEMailで送信するかどうかを取得・設定する。
/// </summary>
internal bool SendEMail {
get { return this.sendEMail; }
set { this.sendEMail = value; }
}
/// <summary>
/// コンストラクタ。
/// </summary>
/// <param name="dateTime">スケジュールの日時</param>
/// <param name="title">タイトル</param>
/// <param name="scheduleText">スケジュール</param>
/// <param name="showAlarm">アラーム表示するかどうか</param>
/// <param name="sendEMail">アラームをEMailで送信するかどうか</param>
internal Schedule(DateTime dateTime, string title, string scheduleText, bool showAlarm, bool sendEMail) {
this.dateTime = dateTime;
this.title = title;
this.scheduleText = scheduleText;
this.showAlarm = showAlarm;
this.sendEMail = sendEMail;
}
}
}3. このクラスのコレクションをViewModel側で以下のように生成しています。
namespace KM_Ora.Schedule.ViewModel {
internal class ScheduleListEditorViewModel : ViewModelBase {
/*
* メンバ変数とプロパティ
*/
private DateTime date;
internal DateTime Date {
set {
this.date = value;
this.Initialize();
}
}
private ObservableCollection<KM_Ora.Schedule.Model.Schedule> scheduleList;
public ObservableCollection<KM_Ora.Schedule.Model.Schedule> ScheduleList {
get { return this.scheduleList; }
set {
this.scheduleList = value;
base.RaisePropertyChanged("ScheduleList");
}
}
/*
* コンストラクタ
*/
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="date">表示するスケジュールの日付</param>
internal ScheduleListEditorViewModel(DateTime date) {
this.date = date;
this.Initialize();
}
/*
* メソッド
*/
/// <summary>
/// 該当日のスケジュールを表示する
/// </summary>
private void Initialize() {
ScheduleGetter getter = new ScheduleGetter();
getter.ReadAll();
List<Model.Schedule> schedules = getter.GetScheduleList(this.date);
this.scheduleList = new ObservableCollection<Model.Schedule>();
this.ScheduleList = new ObservableCollection<Model.Schedule>(schedules);
}
}}
4. このViewModelを、以下の通りにバインドしています。
namespace KM_Ora {
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
/*
KM_Ora.Schedule.View.ScheduleEditor editor = new Schedule.View.ScheduleEditor();
//KM_Ora.Schedule.ViewModel.ScheduleEditorViewModel viewModel = new Schedule.ViewModel.ScheduleEditorViewModel();
//editor.DataContext = viewModel;
DateTime date = new DateTime(2013, 12, 27);
((KM_Ora.Schedule.ViewModel.ScheduleEditorViewModel)editor.DataContext).Date = date;
*/
DateTime date = new DateTime(2013, 12, 27);
KM_Ora.Schedule.View.ScheduleListEditor listEditor = new Schedule.View.ScheduleListEditor();
KM_Ora.Schedule.ViewModel.ScheduleListEditorViewModel listEditViewModel = new Schedule.ViewModel.ScheduleListEditorViewModel(date);
listEditor.DataContext = listEditViewModel;
listEditor.ShowDialog();
}
}
}すると、生成したScheduleクラスのコレクションの数だけ行は表示されるのですが、セルに何も表示されません。
ネットで色々調べて試したのですが、万策尽きてしまいました。
どなたか、セルにデータを表示させるために何が足りないのか、ご教示願います。
回答
-
Scheduleクラスに記述されているプロパティのアクセス修飾をinternalからpublicにしてください。(クラスがinternalになっていることは問題ありません。)
DataContextでプロパティをバインディングする場合、与えられたデータクラスのpublicなプロパティ名のみ調べられてバインディングされるため、internalとなっているプロパティだと見つけてもらえず、DataGridに表示されない状態となってしまってます。あと、時刻列はプロパティ名が不一致なので表示されません。よけいな列が出てしまうのは、AutoGenerateColumnsプロパティをfalseにしておくとよいでしょう。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク 星 睦美 2014年1月7日 1:30
すべての返信
-
Scheduleクラスに記述されているプロパティのアクセス修飾をinternalからpublicにしてください。(クラスがinternalになっていることは問題ありません。)
DataContextでプロパティをバインディングする場合、与えられたデータクラスのpublicなプロパティ名のみ調べられてバインディングされるため、internalとなっているプロパティだと見つけてもらえず、DataGridに表示されない状態となってしまってます。あと、時刻列はプロパティ名が不一致なので表示されません。よけいな列が出てしまうのは、AutoGenerateColumnsプロパティをfalseにしておくとよいでしょう。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク 星 睦美 2014年1月7日 1:30