7

I have trouble to bind a List to a DataGrid. It should be as simple as possible. I'm new to WPF and this is for my personal education.

I have a View(Editor),ViewModel(VMText) and a Data(JustText) class.

My source so far:

JustText.cs

namespace Model
{
    public class Text
    {
        private string _code;
        public string Code
        {
            get { return _code;  }
            set { _code = value; }
        }

        public Text()
        {
            _code = "Hello World!\nHow you doin'?";
        }
    } 
}

VMText.cs

namespace ViewModel
{
    public class VMText
    {    
        private Model.Text _code;

        public List<string> Code
        {            
            get { return new List<string>(_code.Code.Split('\n'));        }
            set { _code.Code = System.String.Join("\n", value.ToArray()); }
        }

        private View.Editor editor;

        public VMText(View.Editor editor)
        {
            _code = new Model.Text();
            this.editor = editor; 
        }
    }
}

Editor.xaml

<Window x:Class="View.Editor"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:View"
        mc:Ignorable="d"
        Title="Editor" Height="240.024" Width="269.895">
    <Grid Background="#FF292929" Margin="0,0,-6.8,0.4">
        <DataGrid x:Name="dataGrid" 
                  HorizontalAlignment="Left" 
                  Margin="0,0,0,0" 
                  VerticalAlignment="Top"
                  Width="200pt"
                  Height="100pt"
                  DataContext="{Binding vmText}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Code, UpdateSourceTrigger=PropertyChanged}" Foreground="Black" Width="60" Header="Test" IsReadOnly="false" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Editor.xaml.cs

namespace View
{
    public partial class Editor : Window
    {
        private ViewModel.VMText vmText;

        #region Constructor

        public Editor()
        {
            InitializeComponent();

            vmText = new ViewModel.VMText(this);
            DataContext = vmText;
        }

        #endregion
    }
}

I just want to show List which is created in VMText in one column in the DataGrid

3
  • 2
    Looks like you need to set the ItemsSource property on the DataGrid. Commented Dec 29, 2016 at 14:33
  • 1
    public List<string> Code {...} is you collection of data for DataGrid, so Bind it in <DataGrid x:Name="dataGrid" ... ItemsSource="{Binding Code}"> Commented Dec 29, 2016 at 14:54
  • 1
    1) ItemsSource="{Binding Code}". Don't set DataContext on the grid at all; it inherits that from the view. 2) That ItemsSource binding won't replace Code; it'll edit the items in Code, which happens to be impossible the way you've written it. With the viewmodel that you have, all you can do is display the items in Code. So Code needs to change: It has to be an ObservableCollection of a class that has a property the grid can edit. Commented Dec 29, 2016 at 14:59

3 Answers 3

16

I guess you simply want to display the strings in the Code source collection property of the view model in the DataGrid. You should

  • then bind the ItemsSource property of the DataGrid to the Code source property of the view model
  • and then bind the DataGridTextColumn to the strings in the Code list itself.

You just have to modify the XAML markup of your view a bit to be able to see the strings. Try this:

<DataGrid x:Name="dataGrid" 
        HorizontalAlignment="Left" 
        Margin="0,0,0,0" 
        VerticalAlignment="Top"
        Width="200pt"
        Height="100pt"
        ItemsSource="{Binding Code}"
        AutoGenerateColumns="False">
   <DataGrid.Columns>
   <DataGridTextColumn 
        Header="Test" IsReadOnly="false" 
        Binding="{Binding}" 
        Foreground="Black" 
        Width="60" />
   </DataGrid.Columns>
</DataGrid>
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, this is working. I tried it with Binding="{Binding Path =.}, too and it is working too. But it is still 'try and error'. I have to figure out the concept of binding.
{Binding} is short for {Binding Path =.}: msdn.microsoft.com/en-us/library/ms750413(v=vs.110).aspx. Please remember to accept an answer and vote helpful ones up.
Thanks, I couldn't understand why I got an additional column called Length... this was caused by the missing AutoGenerateColumns="False" property on the DataGrid.
3

You should implement INotifyPropertyChanged to notify binding that property changed. Also for the collections look at ObservableCollection instead of List.

Comments

1

Bind VMText.Code to DataGrid ItemSource. You don't need to Inicialize DataGrid DataContract in View when you do it in code behind.

ViewModel

namespace ViewModel
{
    public class VMText : INotifyPropertyChanged
    {
        public VMText(View.Editor editor)
        {
            _code = new Model.Text();
            this.editor = editor; 
        }

        public List<string> Code
        {            
            get
            {
                return new List<string>(_code.Code.Split('\n'));
            }
            set
            {
                _code.Code = System.String.Join("\n", value.ToArray());
                NotifyPropertyChanged("Code");
            }
        }

        private void NotifyPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private Model.Text _code;

        private View.Editor editor;
    }
}

View

<Window x:Class="View.Editor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:View"
    mc:Ignorable="d"
    Title="Editor" Height="240.024" Width="269.895">
<Grid Background="#FF292929" Margin="0,0,-6.8,0.4">
    <DataGrid x:Name="dataGrid" 
              HorizontalAlignment="Left" 
              Margin="0,0,0,0" 
              VerticalAlignment="Top"
              Width="200pt"
              Height="100pt"
              ItemsSource="{Binding Code}>
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Code"
                                Foreground="Black" Width="60"
                                Header="Test"
                                IsReadOnly="false" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.