我正在构建一个 WPF MVVM 应用程序。
我有的:
我有一个DataTable
, 绑定到 aDataGrid
这样的:
<DataGrid
Name="Map"
AutoGenerateColumns="True"
AutoGeneratingColumn="Map_AutoGeneratingColumn"
IsReadOnly="True"
ItemsSource="{Binding MapDataTable}" />
这是我在以下位置创建数据表的方式ViewModel
:
ObservableCollection<ObservableCollection<MapModel>> MapDataList { get; set; }
private void CreateDataTable(IEnumerable<MapModel> mapDataItems)
{
MapDataTable.Clear();
DataTable dataTable = new DataTable("MapDataTable");
dataTable.Columns.Add("First", typeof(string));
dataTable.Columns.Add("Second", typeof(string)); //typeof might need to be changed to ObservableCollection<SomeModel> (still works) or ComboBox
var mapData = new ObservableCollection<MapModel>();
foreach (var item in mapDataItems)
{
mapData.Add(item);
}
MapDataList.Add(mapData);
foreach (MapModel item in mapDataItems)
{
DataRow dataRow = dataTable.NewRow();
dataRow[0] = item.Name;
dataRow[1] = item.SomeValues; //mistake could be here
dataTable.Rows.Add(dataRow);
}
MapDataTable = dataTable;
}
MapModel.cs:
public class MapModel
{
public string Name { get; set; }
public ObservableCollection<SomeModel> SomeValues { get; set; } = new ObservableCollection<SomeModel>
{
new SomeModel(),
new SomeModel()
};
}
SomeModel.cs:
public class SomeModel
{
public string Name { get; set; }
public double Value { get; set; }
public SomeModel()
{
Name = "test";
Value = 0;
}
}
xaml.cs 中的 Map_AutoGeneratingColumn:
if (e.PropertyName == "Second")
{
var templateColumn = new DataGridTemplateColumn
{
Header = e.PropertyName,
CellTemplate = (sender as FrameworkElement).FindResource("SecondCellTemplate") as DataTemplate,
CellEditingTemplate = (sender as FrameworkElement).FindResource("SecondCellEditingTemplate") as DataTemplate
};
e.Column = templateColumn;
}
在视图中:
<Grid.Resources>
<DataTemplate x:Key="SecondCellTemplate">
<TextBlock Text="{Binding Path=???, Mode=OneWay}" />
</DataTemplate>
<DataTemplate x:Key="SecondCellEditingTemplate">
<ComboBox
DisplayMemberPath="Name"
ItemsSource="{Binding Path=SomeValues, Mode=OneWay}" //wrong binding
SelectedValue="{Binding Path=???, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Name" />
</DataTemplate>
</Grid.Resources>
我想要达到的目标:
我希望SomeValues
' 名称显示ComboBox
在DataGridTemplateColumn
.
我如何实现这一目标?
编辑:
从这个评论(https://stackoverflow.com/a/35212223/17198402)我了解如何绑定SomeValues
如果列是硬编码而不是自动生成的,但是当它们自动生成时我仍然无法理解如何去做. 在代码隐藏中设置ItemsSource
对我来说仍然是一个谜。据我了解,DataGridTemplateColumn
不继承DataContext
, 不像DataGridTextColumn
.
编辑2:
我能够以ViewModel
这种方式绑定到一个属性:
视图模型.cs
public ObservableCollection<SomeModel> SomeValues { get; set; } = new ObservableCollection<SomeModel>
{
new SomeModel(),
new SomeModel()
};
xml:
<Grid.Resources>
<DataTemplate x:Key="SecondColumnTemplate" DataType="DataGridCell">
<ComboBox
DisplayMemberPath="Name"
ItemsSource="{Binding Path=DataContext.SomeValues, RelativeSource={RelativeSource AncestorType=Page}}" />
</DataTemplate>
</Grid.Resources>
自动生成列:
var templateColumn = new DataGridTemplateColumn
{
Header = e.PropertyName,
CellTemplate = (sender as FrameworkElement).FindResource("SecondColumnTemplate") as DataTemplate
};
e.Column = templateColumn;
这成功地绑定了 ViewModel 中的新属性,但这当然不是我想要的。如何绑定到当前item.SomeValues
?