WPF DataGrid在同一列中的不同控件 - 不正确的绑定
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF DataGrid在同一列中的不同控件 - 不正确的绑定相关的知识,希望对你有一定的参考价值。
我正在开发应用程序,它对项目列表执行检查。每个项目都有需要对其执行的检查列表。每个检查可以是3种类型之一:CheckBox,ComboBox,TextBox。
我想让Datagrid有2列(一个用于项目名称,第二列用于检查列表)。第二列包含另一个具有2列的DataGrid(一列用于检查名称,第二列用于检查控制)。目的是在与Check模型绑定的同一列中使用不同类型的控件。
问题是与CheckValue的绑定不起作用,但与所有其他属性的绑定工作正常。
最后一列包含CheckBoxes,TextBox和ComboBox,但它们没有填充任何值。有谁知道下面的代码有什么问题?
以下是模型类的示例
public class Item
{
public string ItemName { get; set; }
public ObservableCollection<Check> Checks { get; set; }
public Item()
{
Checks = new ObservableCollection<Check>();
}
}
public enum CheckType
{
CheckBox,
ComboBox,
TextBox
}
public abstract class Check
{
public string CheckName { get; set; }
public CheckType CheckType { get; protected set; }
public abstract object CheckValue { get; set; }
}
public class CheckBox : Check
{
private bool checkValue;
public CheckBox()
{
CheckType = CheckType.CheckBox;
}
public override object CheckValue
{
get
{
return checkValue;
}
set
{
checkValue = (bool)value;
}
}
}
public class ComboBox : Check
{
private List<string> checkValue;
public ComboBox()
{
CheckType = CheckType.ComboBox;
}
public override object CheckValue
{
get
{
return checkValue;
}
set
{
checkValue = value as List<string>;
}
}
}
public class TextBox : Check
{
private string checkValue;
public TextBox()
{
CheckType = CheckType.TextBox;
}
public override object CheckValue
{
get
{
return checkValue;
}
set
{
checkValue = value as string;
}
}
}
public class MainViewModel
{
public ObservableCollection<Item> Items { get; set; }
public MainViewModel()
{
Items = new ObservableCollection<Item>();
Item item = new Item();
item.ItemName = "First item";
Check check1 = new CheckBox() { CheckName = "Check 1", CheckValue = true };
Check check2 = new CheckBox() { CheckName = "Check 2", CheckValue = false };
Check text1 = new TextBox() { CheckName = "Check 3", CheckValue = "Please enter check" };
Check combo1 = new ComboBox() { CheckName = "Check 4", CheckValue = new List<string> { "Value1", "Value2" } };
item.Checks.Add(check1);
item.Checks.Add(check2);
item.Checks.Add(text1);
item.Checks.Add(combo1);
Items.Add(item);
}
}
最后这里是主窗口的XAML代码。
<Window x:Class="ItemTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm ="clr-namespace:ItemTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<vm:MainViewModel x:Key="mainViewModel"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource mainViewModel}}">
<DataGrid ItemsSource="{Binding Path=Items}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Item" Binding="{Binding ItemName}" />
<DataGridTemplateColumn Header="Checks">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DataGrid ItemsSource="{Binding Checks}" AutoGenerateColumns="False" HeadersVisibility="None">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding CheckName}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding CheckType}" Value="CheckBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsChecked="{Binding CheckValue}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CheckType}" Value="ComboBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ComboBox ItemsSource="{Binding CheckValue}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CheckType}" Value="TextBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding CheckValue}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
只需设置ItemControl的Content属性:
<ContentControl Content="{Binding}">
WPF将自动将DataTemplate的DataContext设置为其父ContentControl的内容。但是在您的XAML中,您没有设置Content属性(您只指定ContentControl的Style,但忘记设置其内容)。
并且不要忘记在控件绑定上设置UpdateSourceTrigger=PropertyChanged
,否则您可能在viewmodel中看不到更新。
XAML示例工作,绑定BindingList:
<DataGrid x:Name="dataGridParametros"
Grid.Row="1"
Margin="5"
AutoGenerateColumns="False"
HeadersVisibility="All"
ItemsSource="{Binding}"
RowHeaderWidth="20"
SelectionUnit="FullRow"
ScrollViewer.CanContentScroll="True"
CanUserAddRows="false"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
FontFamily="Arial"
CellEditEnding="dataGridParametros_CellEditEnding" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding IdParametro}" Header="Id" FontFamily="Arial" IsReadOnly="True" Visibility="Hidden"/>
<DataGridTextColumn Binding="{Binding Codigo}" Header="Código" FontFamily="Arial" IsReadOnly="True"/>
<DataGridTextColumn Width="200" Binding="{Binding Mnemonico}" Header="Mnemonico" FontFamily="Arial" IsReadOnly="True" />
<DataGridTextColumn Width="250*" Binding="{Binding Descricao}" Header="Descrição" FontFamily="Arial" IsReadOnly="True" />
<DataGridTemplateColumn Header="Valor" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding TipoCampo}" Value="CheckBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsChecked="{Binding Valor , Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding TipoCampo}" Value="ComboBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ComboBox ItemsSource="{Binding Valor , Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding TipoCampo}" Value="TextBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Valor , Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
以上是关于WPF DataGrid在同一列中的不同控件 - 不正确的绑定的主要内容,如果未能解决你的问题,请参考以下文章
WPF 在datagrid模板列中添加用户控件,在后台如何快速的检索到该控件。急!!!
WPF 格式化输出- IValueConverter接口的使用 datagrid列中的值转换显示