for my work I need to generate datagrids via code behind. The datagrids contain 2 columns: Questions (Just text, which should not be editable) and "Answers" which needs a textBox or comboBox based on an enum.
I tried to bind a list of questions (Containing the text and an answer field) to the datagrid. The question column works just fine. But the textboxes don't receive any value. I can type in them, but once I sort the datagrid all values are gone. In the itemsource of the data grid I can see that the values doesn't update at all:/
After this failure I tried this with normal datagrid in XAML but it doesn't work either. The column for answers is a DataGridTemplate Column.
Here is my xaml:
<Window x:Class="BindingTest.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"
xmlns:local="clr-namespace:BindingTest"
xmlns:t="clr-namespace:BindingTest;assembly=BindingTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate x:Key="AnswerTemp">
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding Typ}" Value="{x:Static t:QuestionType.Numeric}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Path=Answer,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<DataGrid x:Name="MetaDataGrid" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Questions" Binding="{Binding Text}">
</DataGridTextColumn>
<DataGridTemplateColumn Header="Answers" CellTemplate="{StaticResource ResourceKey=AnswerTemp}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Code behind:
// Just contains a Dictionary <string,QuestionBlock> called SeperatorList
public static ActualPage actualPage = new ActualPage();
public MainWindow()
{
InitializeComponent();
QuestionBlock seperator = new QuestionBlock();
seperator.Questions = new ObservableCollection<Question>();
for (int counter = 1; counter < 11; counter++)
seperator.Questions.Add(new Question() { Text = $"What is the {counter}. Answer?", Answer = $"{5 + counter}", Typ = QuestionType.Numeric, Names = new List<string>() { "1", "2", "3" } });
actualPage.SeperatorList.Add("Test", seperator);
MetaDataGrid.ItemsSource = seperator.Questions;
}
Code in QuestionBlock:
public class QuestionBlock : INotifyPropertyChanged
{
private ObservableCollection<Question> _questionBlock;
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<Question> Questions
{
get => _questionBlock;
set
{
_questionBlock = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Questions)));
}
}
}
Code in Question:
public class Question : INotifyPropertyChanged
{
private string _text;
private string _answer;
private QuestionType _typ;
public event PropertyChangedEventHandler PropertyChanged;
public string Text
{
get => _text;
set
{
_text = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text)));
}
}
public string Answer
{
get => _answer;
set
{
_answer = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Answer)));
}
}
public QuestionType Typ
{
get => _typ;
set
{
_typ = value;
}
}
}
What am I doing wrong here? Note: The values that should be included in the comboBox are not enum values. There are values from a string list: Any help would be appreciated :)
You should put the editable control in the CellEditingTemplate
of the column:
<DataGridTemplateColumn Header="Answers" CellEditingTemplate="{StaticResource AnswerTemp}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Answer}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
...and bind the TextBox
to the Answer
property of the DataContext
of the ContentControl
:
<DataTemplate x:Key="AnswerTemp">
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding Typ}" Value="{x:Static t:QuestionType.Numeric}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Path=DataContext.Answer,
RelativeSource={RelativeSource AncestorType=ContentControl}}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
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.