none
WPF DataGridにバインドしたデータが表示されない RRS feed

  • 質問

  • 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クラスのコレクションの数だけ行は表示されるのですが、セルに何も表示されません。

    ネットで色々調べて試したのですが、万策尽きてしまいました。

    どなたか、セルにデータを表示させるために何が足りないのか、ご教示願います。

    2013年12月30日 3:56

回答

  • Scheduleクラスに記述されているプロパティのアクセス修飾をinternalからpublicにしてください。(クラスがinternalになっていることは問題ありません。)
    DataContextでプロパティをバインディングする場合、与えられたデータクラスのpublicなプロパティ名のみ調べられてバインディングされるため、internalとなっているプロパティだと見つけてもらえず、DataGridに表示されない状態となってしまってます。

    あと、時刻列はプロパティ名が不一致なので表示されません。よけいな列が出てしまうのは、AutoGenerateColumnsプロパティをfalseにしておくとよいでしょう。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク 星 睦美 2014年1月7日 1:30
    2013年12月30日 7:17

すべての返信

  • Scheduleクラスに記述されているプロパティのアクセス修飾をinternalからpublicにしてください。(クラスがinternalになっていることは問題ありません。)
    DataContextでプロパティをバインディングする場合、与えられたデータクラスのpublicなプロパティ名のみ調べられてバインディングされるため、internalとなっているプロパティだと見つけてもらえず、DataGridに表示されない状態となってしまってます。

    あと、時刻列はプロパティ名が不一致なので表示されません。よけいな列が出てしまうのは、AutoGenerateColumnsプロパティをfalseにしておくとよいでしょう。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク 星 睦美 2014年1月7日 1:30
    2013年12月30日 7:17
  • gekka 様

    解決できしました。

    今回、アクセス修飾子を厳密に使おうとしていて、別のクラスでもpublicにしていたためプロパティが機能しないと言う経験をしていたのに、うかつでした。

    本当にありがとうございました。

    FabbricaKM

    2013年12月31日 0:45