简体   繁体   中英

How to bind a list to datagrid columns in wpf

I have a class containting 7 list strings(sun, mon, tue...). In my class, I am populating these list strings with the days in a month. I then create another list and added the result to it. For example, if we take January 2019, sun will have the values, 6, 13, 20 and 27. I then make my grids itemsource to be this list but then my grid is blank. Below is my code, what am I missing or doing wrong?

model

    public class MonthModel
   {
    //public string sun { get; set; }
    public List<string> sun = new List<string>();     
    public List<string> mon = new List<string>();
    public List<string> tue = new List<string>();
    public List<string> wed = new List<string>();
    public List<string> thu = new List<string>();
    public List<string> fri = new List<string>();
    public List<string> sat = new List<string>();

}

class

         switch (cTvDaySelected)
        {

                case "January":
                int Year = DateTime.Today.Year;
                int Month = 1;                 
                int TotalDaysInMonth = DateTime.DaysInMonth(Year, Month);

                    for (int i = 1; i <= TotalDaysInMonth; i++)
                    {
                        DateTime dt = new DateTime(Year, Month, i);
                        if (dt.DayOfWeek.ToString().ToLower().Substring(0, 3) == "sun")
                        {
                            dm.sun.Add(dt.ToShortDateString().Substring(0, 2));                 
                            //dm.sun = dt.ToShortDateString().Substring(0, 2);
                        }
                        if (dt.DayOfWeek.ToString().ToLower().Substring(0, 3) == "mon")
                        {
                        // dm.mon = dt.ToShortDateString().Substring(0, 2);
                          dm.mon.Add(dt.ToShortDateString().Substring(0, 2));
                    }
                        if (dt.DayOfWeek.ToString().ToLower().Substring(0, 3) == "tue")
                        {
                        // dm.tue = dt.ToShortDateString().Substring(0, 2);
                        dm.tue.Add(dt.ToShortDateString().Substring(0, 2));
                    }
                        if (dt.DayOfWeek.ToString().ToLower().Substring(0, 3) == "wed")
                        {
                        //dm.wed = dt.ToShortDateString().Substring(0, 2);
                        dm.wed.Add(dt.ToShortDateString().Substring(0, 2));
                    }
                        if (dt.DayOfWeek.ToString().ToLower().Substring(0, 3) == "thu")
                        {
                        //dm.thu = dt.ToShortDateString().Substring(0, 2);
                        dm.thu.Add(dt.ToShortDateString().Substring(0, 2));
                    }
                        if (dt.DayOfWeek.ToString().ToLower().Substring(0, 3) == "fri")
                        {
                        //dm.fri = dt.ToShortDateString().Substring(0, 2);
                        dm.fri.Add(dt.ToShortDateString().Substring(0, 2));
                    }
                        if (dt.DayOfWeek.ToString().ToLower().Substring(0, 3) == "sat")
                        {
                        // dm.sat = dt.ToShortDateString().Substring(0, 2);
                          dm.sat.Add(dt.ToShortDateString().Substring(0, 2));
                    }

                    }
                    Month_Model.Add(dm);

               // month_record.Items.Add(dm);

                month_record.ItemsSource = Month_Model;
                 break;
        }

xaml

   <DataGrid x:Name="month_record"  MouseDoubleClick="Month_record_MouseDoubleClick" 
     IsReadOnly="True" Grid.ColumnSpan="9" Grid.Column="1" SelectionMode="Extended" 
   SelectionUnit="Cell" VerticalGridLinesBrush="Silver" HorizontalGridLinesBrush="Silver" 
   AutoGenerateColumns="False" ScrollViewer.VerticalScrollBarVisibility="Visible" 
   ScrollViewer.HorizontalScrollBarVisibility="Visible" Visibility="Hidden" Grid.Row="4" >
   <DataGrid.Columns>
  <DataGridTextColumn Binding="{Binding sun}" IsReadOnly="True" x:Name="colMSun" Header="Sunday" 
  Width="Auto">
  <DataGridTextColumn.ElementStyle>
    <Style TargetType="{x:Type TextBlock}">
    <Style.Triggers>
    <Trigger Property="Text" Value="B">
    <Setter Property="Background" Value="#C1D5F8"/>
    </Trigger>
    </Style.Triggers>
     </Style>
    </DataGridTextColumn.ElementStyle>
     </DataGridTextColumn>
    <DataGridTextColumn Binding="{Binding Path=mon}" x:Name="colMMon" 
   IsReadOnly="True" Header="Monday" Width="Auto">
   <DataGridTextColumn.ElementStyle>
   <Style TargetType="{x:Type TextBlock}">
     <Style.Triggers>
     <Trigger Property="Text" Value="B">
     <Setter Property="Background" Value="#C1D5F8"/>
      </Trigger>
      </Style.Triggers>
     </Style>
    </DataGridTextColumn.ElementStyle>
     </DataGridTextColumn>
      <DataGridTextColumn Binding="{Binding Path=tue}" x:Name="colMTue" 
       IsReadOnly="True" Header="Tuesday" Width="Auto">
       <DataGridTextColumn.ElementStyle>
       <Style TargetType="{x:Type TextBlock}">
        <Style.Triggers>
        <Trigger Property="Text" Value="B">
         <Setter Property="Background" Value="#C1D5F8"/>
         </Trigger>
         </Style.Triggers>
          </Style>
          </DataGridTextColumn.ElementStyle>
           </DataGridTextColumn>
           <DataGridTextColumn Binding="{Binding Path=wed}" IsReadOnly="True" 
            x:Name="colMWed" Header="Wednesday" Width="Auto">
            <DataGridTextColumn.ElementStyle>
             <Style TargetType="{x:Type TextBlock}">
              <Style.Triggers>
               <Trigger Property="Text" Value="B">
                <Setter Property="Background" Value="#C1D5F8"/>
                </Trigger>
                  </Style.Triggers>
                  </Style>
                  </DataGridTextColumn.ElementStyle>
                  </DataGridTextColumn>
                  <DataGridTextColumn Binding="{Binding Path=thu}" IsReadOnly="True" 
                   x:Name="colMThu" Header="Thursday" Width="Auto">
                   <DataGridTextColumn.ElementStyle>
                     <Style TargetType="{x:Type TextBlock}">
                    <Style.Triggers>
                    <Trigger Property="Text" Value="B">
                    <Setter Property="Background" Value="#C1D5F8"/>
                    </Trigger>
                      </Style.Triggers>
                       </Style>
                       </DataGridTextColumn.ElementStyle>
                      </DataGridTextColumn>
                      <DataGridTextColumn Binding="{Binding Path=fri}" x:Name="colMFri" 
                      IsReadOnly="True" Header="Friday" Width="Auto">
                      <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                         <Style.Triggers>
                          <Trigger Property="Text" Value="B">
                            <Setter Property="Background" Value="#C1D5F8"/>
                              </Trigger>
                                </Style.Triggers>
                               </Style>
                         </DataGridTextColumn.ElementStyle>
                          </DataGridTextColumn>
                          <DataGridTextColumn Binding="{Binding Path=sat}" x:Name="colMSat" 
                           IsReadOnly="True" Header="Saturday" Width="Auto">
                            <DataGridTextColumn.ElementStyle>
                            <Style TargetType="{x:Type TextBlock}">
                              <Style.Triggers>
                               <Trigger Property="Text" Value="B">
                                 <Setter Property="Background" Value="#C1D5F8"/>
                                  </Trigger>
                                  </Style.Triggers>
                               </Style>
                              </DataGridTextColumn.ElementStyle>
                         </DataGridTextColumn>
                        </DataGrid.Columns>                              
                     </DataGrid>

There are couple of issues with your code.

  1. You have made your data grid Visibility to "Hidden". So you are not able to see anything in your window.

  2. You are trying to bind a collection to a TextBlock. This is the your question too.

You cannot bind a collection to a TextBlock. If you wanted to achieve this then you can have a ComboBox in your DataGrid cell and bind the list to it.

Or else

You can follow below steps where I have made a concatenation of each property as a comma separated string.

  1. Your class members are fields and not properties. I am not sure if this also a problem but the moment I have changed them to properties, I can able to see something coming up in Columns.

So I have made changes following,

  1. Changed class level public fields to properties - You can ignore this because the actual data I am binding to DataGridTextColumn is "Sunday" (a property) of my MonthModel class. So doing this is not very mandatory but your "Sunday" should be a property.

See below for the updated class.

    public class MonthModel
    {
        public List<string> sun { get; set; } = new List<string>();
        public List<string> mon { get; set; } = new List<string>();
        public List<string> tue { get; set; } = new List<string>();
        public List<string> wed { get; set; } = new List<string>();
        public List<string> thu { get; set; } = new List<string>();
        public List<string> fri { get; set; } = new List<string>();
        public List<string> sat { get; set; } = new List<string>();


        public string Sunday
        {
            get
            {
                return string.Join(",", sun);
            }
        }
    }

Note:- I have created only a single property "Sunday" and concatenating the list as a "," (comma) separated string.

You can create similar way for other properties or change it according to your needs.

Approach 1 -

  1. Visibility of DataGrid made to Visible (hope you missed this at first point) and I am now binding "Sunday" property to DataGridTextColumn

     <DataGrid x:Name="month_record" MouseDoubleClick="month_record_MouseDoubleClick" IsReadOnly="True" Grid.ColumnSpan="9" Grid.Column="1" SelectionMode="Extended" SelectionUnit="Cell" VerticalGridLinesBrush="Silver" HorizontalGridLinesBrush="Silver" AutoGenerateColumns="False" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible" Visibility="Visible" Grid.Row="4"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Sunday}" IsReadOnly="True" x:Name="colMSun" Header="Sunday" Width="Auto"> <DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Style.Triggers> <Trigger Property="Text" Value="Sunday"> <Setter Property="Background" Value="Red"/> </Trigger> </Style.Triggers> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> </DataGrid.Columns> </DataGrid> }

Note:- I am not pasting all columns here, but you have to do it on yourself. I hope you can able to make changes with above changes.

I haven't made any changes to code-behind of your methods.

Approach 2 -

If you are okay to have a combobox in your datagrid column then see below small code snippet,

              <DataGridTemplateColumn Header="Combobox">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox SelectedIndex="0" ItemsSource="{Binding sun}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

Hope any of the above approaches might helps you. If not then let us know your alternative ideas on how you wanted to represent UI so that we can have a better ideas.

Suggestions:-

And small suggestions from my end after looking at your code

Use observable collection and bind as an source to your DataGrid.

Implement INotifyPropertyChanged to listen for the value changes and refresh UI automatically.

Improve your naming conventions that you give to your class, properties, objects.

Hope this helps. Please give a try and let us know in case if any issues exists.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM