How to bind entities from Entity Framework to DataGrid?

11,152

Instead of DataContext, set ItemsSource to the result set.

gridMessages.ItemsSource = result;

Note Since you're new to WPF, you might want to note that MVVM is better than the approach here, for separating UI from business logic. To use an MVVM approach, you'd set your Window's DataContext to some View Model class:

private void messagesWindow_Loaded(object sender, RoutedEventArgs e) 
{ 
    Model = new ViewModel();
    this.DataContext = Model;
    // TODO set Model.Messages to the EF result set
}

Where the ViewModel looks something like this:

public class ViewModel : INotifyPropertyChanged
{
    private List<Message> _messages;

    public List<Message> Messages
    {
        get { return _messages; }
        set
        {
            _messages = value;
            RaisePropertyChanged("Messages");
        }
    }

    // TODO implement INotifyPropertyChanged
}

Then bind the DataGrid's ItemsSource to your a property.

<DataGrid ItemsSource="{Binding Messages}" Grid.Row="1"/>
Share:
11,152

Related videos on Youtube

pmichna
Author by

pmichna

Software developer

Updated on August 22, 2022

Comments

  • pmichna
    pmichna over 1 year

    My XAML:

    <Window x:Class="Newsletter.UI.MessagesWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MessagesWindow" Name="messagesWindow" Height="576" Width="1024" WindowStartupLocation="CenterScreen" Closed="MessagesWindowClosed">
        <Window.Resources>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Width" Value="149"/>
                <Setter Property="Margin" Value="10"/>
            </Style>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="75"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0"  Orientation="Horizontal" HorizontalAlignment="Center">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Button Name="saveButton" Grid.Row="0" Content="Save"  Margin="10,10,10,5"/>
                    <TextBox Name="searchTextBox" Grid.Row="1"  Margin="10,5,10,10"/>
                </Grid>
                <Button Name="recipientsButton" Content="RECIPIENTS" Click="RecipientsButtonClick" />
                <Button Name="createButton" Content="CREATE" Click="CreateButtonClick" />
                <Button Name="removeButton" Content="REMOVE" />
                <Button Name="editButton" Content="EDIT" />
                <Button Name="resendButton" Content="RESEND"/>
            </StackPanel>
            <DataGrid Name="gridMessages" Grid.Row="1"/>
        </Grid>
    </Window>
    

    My .cs code:

    private void messagesWindow_Loaded(object sender, RoutedEventArgs e)
            {
                using (NewsletterEntities context = new NewsletterEntities())
                {
                    var query = from m in context.Messages select m;
                    var result = query.ToList();
                    gridMessages.DataContext = result;
                }
            }
    

    Message class generated by EF:

    [EdmEntityTypeAttribute(NamespaceName="NewsletterModel", Name="Message")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Message : EntityObject
    {
        #region Factory Method
    
    /// <summary>
    /// Create a new Message object.
    /// </summary>
    /// <param name="messageID">Initial value of the MessageID property.</param>
    /// <param name="subject">Initial value of the Subject property.</param>
    /// <param name="content">Initial value of the Content property.</param>
    /// <param name="hasAttachments">Initial value of the HasAttachments property.</param>
    /// <param name="senderID">Initial value of the SenderID property.</param>
    /// <param name="date">Initial value of the Date property.</param>
    public static Message CreateMessage(global::System.Int32 messageID, global::System.String subject, global::System.String content, global::System.Boolean hasAttachments, global::System.Int32 senderID, global::System.DateTime date)
    {
        Message message = new Message();
        message.MessageID = messageID;
        message.Subject = subject;
        message.Content = content;
        message.HasAttachments = hasAttachments;
        message.SenderID = senderID;
        message.Date = date;
        return message;
    }
    
    #endregion
    
    #region Primitive Properties
    
    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.Int32 MessageID
    {
        get
        {
            return _MessageID;
        }
        set
        {
            if (_MessageID != value)
            {
                OnMessageIDChanging(value);
                ReportPropertyChanging("MessageID");
                _MessageID = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("MessageID");
                OnMessageIDChanged();
            }
        }
    }
    private global::System.Int32 _MessageID;
    partial void OnMessageIDChanging(global::System.Int32 value);
    partial void OnMessageIDChanged()
    

    Unfortunately nothing happens, the DataGrid is empty. I'm new to data binding in WPF and EF. I hope this problem is simple but I have no idea how to solve it.

  • pmichna
    pmichna over 11 years
    I tried this before - didn't help. I have data in the Messages table, so it should display something.
  • McGarnagle
    McGarnagle over 11 years
    @vtvs that's very strange, it should work. All the DataGrid needs to work is an ItemsSource...
  • pmichna
    pmichna over 11 years
    Yes, I have separeted UI from Logic. I have one project for UI, another for DAL and another for Services. However, I just wanted to test wheter binding works and then organize everything correctly. I'll take a look a MVVM later, now I just need to get the DataGrid working. Any ideas why it doesn't work?
  • McGarnagle
    McGarnagle over 11 years
    Assuming you've breakpointed gridMessages.DataContext = result; and confirmed that results has items, then I'm out of ideas. :( All I can suggest is, first, make sure you can get your result set into a plain ListBox; second, try switching off AutoGenerateColumns on the DataGrid, and define them manually.
  • pmichna
    pmichna over 11 years
    Crap, somehow I Loaded event was not connected to the mentioned method. Now it works. Thanks!