我是WPF的新手,所以请为任何“愚蠢”的错误道歉。 我有一个只有一列的数据网格,即一个组合框。数据网格按预期显示一个新的空行。但是如果我在新行上的组合框中选择一个值,则不会添加额外的新行。我已经尝试根据这个答案添加一个编辑模板:datagrid showing one new row, but not any subsequent但是没有任何帮助。
<Window x:Class="WPFSpielplatz.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="clr-namespace:WPFSpielplatz"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<d:MainWindowViewModel />
</Window.DataContext>
<Grid>
<StackPanel HorizontalAlignment="Left" Height="319" VerticalAlignment="Top" Width="517">
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GroceryItems}" CanUserAddRows="True">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Combo">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.GroceryItemTypes}" SelectedItem="{Binding GroceryItemType, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name" ></ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.GroceryItemTypes}" SelectedItem="{Binding GroceryItemType, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name" ></ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>
我的ViewModel:
using System.Collections.ObjectModel;
using System.ComponentModel;
using WPFSpielplatz.Annotations;
namespace WPFSpielplatz
{
public class MainWindowViewModel:INotifyPropertyChanged
{
private ObservableCollection<GroceryItem> _groceryItems;
public MainWindowViewModel()
{
GroceryItemTypes = new ObservableCollection<GroceryItemType>
{
new GroceryItemType("Food"),
new GroceryItemType("Non-Food")
};
_groceryItems=new ObservableCollection<GroceryItem>
{
new GroceryItem(){GroceryItemType=GroceryItemTypes[0]},
new GroceryItem(){GroceryItemType=GroceryItemTypes[1]}
};
}
public ObservableCollection<GroceryItem> GroceryItems
{
get { return _groceryItems; }
set
{
_groceryItems = value;
OnPropertyChanged("GroceryItems");
}
}
public ObservableCollection<GroceryItemType> GroceryItemTypes { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
“域名”类:
GroceryItem:
namespace WPFSpielplatz
{
public class GroceryItem
{
public GroceryItemType GroceryItemType { get; set; }
public GroceryItem()
{
}
}
}
GroceryItemType:
namespace WPFSpielplatz
{
public class GroceryItemType
{
public GroceryItemType()
{
}
public GroceryItemType(string name)
{
Name = name;
}
public string Name { get; set; }
}
}
答案 0 :(得分:0)
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GroceryItems}"/>
足以将您的集合绑定到DataGrid。它已经是相对的,但您只需要将GroceryItem
类的属性绑定到DataGrid,如下所示:
<ComboBox ItemsSource="{Binding GroceryItemType.Name, Mode=TwoWay"}/>
这会将每个GroceryItemType
的名称插入到ComboBox中关联的GroceryItem
。您可能最终只在ComboBox中使用GroceryItemType
的名称,因为您确实将其指定为ItemsSource
。我不认为这是你想要的,但是现在,我没有看到任何更多的代码来理解你想要存档的内容。
请注意,如果您想要反映对ViewModel的更改,并且两个模型(INotifyPropertyChanged
和GroceryItem
)必须实施GroceryItemType
反之亦然。这就是Mode=TwoWay
派上用场的地方。
答案 1 :(得分:0)
好的,我解决了。它一直有效,问题是,我的<DataGridTemplateColumn.CellTemplate>
和我的<DataGridTemplateColumn.CellEditingTemplate>
看起来一样,所以我可以在没有进入编辑模式的情况下更改组合框中的值。但只有在进入并成功退出编辑模式后,才会向数据网格添加新行。
要实现此功能,您必须在要编辑的单元格中单击多次次,然后单击选项卡以添加新行。
因此,View的更新代码如下所示:
<Window x:Class="WPFSpielplatz.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="clr-namespace:WPFSpielplatz"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<d:MainWindowViewModel />
</Window.DataContext>
<Grid>
<StackPanel HorizontalAlignment="Left" Height="319" VerticalAlignment="Top" Width="517">
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GroceryItems}" CanUserAddRows="True">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Combo">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=GroceryItemType.Name}" ></TextBlock>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel>
<TextBlock>Edit</TextBlock>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.GroceryItemTypes}" SelectedItem="{Binding GroceryItemType, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name" ></ComboBox>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>