A.B.
A.B.

Reputation: 2470

Binding a string list to a DataGridTemplateColumn TextBox

If I try to do that, I get "System.Windows.Markup.XamlParseException".

My XAML code looks like this:

<Window x:Class="WpfApplication1.MainWindow"
        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"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid ItemsSource="{Binding ErrorLog}" AutoGenerateColumns="False" IsReadOnly="True" CanUserAddRows="False" CanUserDeleteRows="False">
            <DataGrid.Columns>
                <!-- This is working -->
                <DataGridTextColumn Binding="{Binding}" Header="Fehler" Width="*"/>

                <!-- This is not working -->
                <DataGridTemplateColumn Header="">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding}" AcceptsReturn="True" AcceptsTab="True" TextWrapping="Wrap"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

My code behind code looks like this:

using System.Collections.ObjectModel;
using System.Windows;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        public ObservableCollection<string> ErrorLog { get; set; } = new ObservableCollection<string>()
        {
            "A",
            "B"
        };
    }
}

Upvotes: 0

Views: 1043

Answers (1)

Yevgeniy
Yevgeniy

Reputation: 1066

Additional information from exception is: Two-way binding requires Path or XPath. TextBox Text property has TwoWay binding mode by default. TwoWay bindings do not accept empty bindings like "{Binding}". Try the following.

<DataGridTemplateColumn Header="">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Path=.}" AcceptsReturn="True" AcceptsTab="True" TextWrapping="Wrap"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

I think, changing your collection type and using some custom type instead of string will be a better solution though: XAML:

<Grid>
    <DataGrid ItemsSource="{Binding ErrorLog}" AutoGenerateColumns="False" IsReadOnly="True" CanUserAddRows="False" CanUserDeleteRows="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Message}" Header="Fehler" Width="*"/>
            <DataGridTemplateColumn Header="">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Message}" AcceptsReturn="True" AcceptsTab="True" TextWrapping="Wrap"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

Code-behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainViewModel();
    }
}

public class MainViewModel
{
    public ObservableCollection<Error> ErrorLog { get; set; } = new ObservableCollection<Error>
                                                                    {
                                                                        new Error("A"),
                                                                        new Error("B"),
                                                                    };
}

public class Error
{
    public Error(string message)
    {
        Message = message;
    }

    public string Message { get; set; }
}

Also consider implement INotifyPropertyChanged interface to be able to change message from view model if needed.

Upvotes: 1

Related Questions