WPF MVVM 数据绑定问题
WPF MVVM Data Binding issue
我的ViewModel
如下:
public class ShipDataCollectViewModel : ViewModelBase
{
//private ObservableCollection<Item> _scannedItems;
//private Item _scanningItem;
public ObservableCollection<Item> ScannedItems
{
get;
private set;
}
public Item ScanningItem
{
get;
private set;
}
public ShipDataCollectViewModel()
{
ScannedItems = new ObservableCollection<Item>();
ScanningItem = new Item();
AddItemCommand = new RelayCommand(AddItem, CanAddItem);
}
private RelayCommand _addItemCommand;
public RelayCommand AddItemCommand { get; private set; }
private void AddItem()
{
//var item = new Item { ItemNo = _scanningItem.ItemNo, Qty = _scanningItem.Qty, Box = _scanningItem.Box, SerialNo = _scanningItem.SerialNo };
//ScannedItems.Add(item);
//Cannot use the following code, it will overwrite all the ObservableCollection's items if exist.
ScannedItems.Add(ScanningItem);
}
private bool CanAddItem()
{
return true;
}
}
View
如下:
<Grid>
<Grid HorizontalAlignment="Left" Height="114" Margin="10,10,0,0" VerticalAlignment="Top" Width="722">
<Label Content="Customer No:" HorizontalAlignment="Left" Height="27" Margin="5,5,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="104,5,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="108"/>
<Label Content="PO No:" HorizontalAlignment="Left" Height="27" Margin="258,5,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="354,5,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="108"/>
<Label Content="SO No:" HorizontalAlignment="Left" Height="27" Margin="5,40,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="104,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="108"/>
<Label Content="Vendor:" HorizontalAlignment="Left" Height="27" Margin="255,40,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="354,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="108"/>
<Label Content="Invoice No:" HorizontalAlignment="Left" Height="27" Margin="5,72,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="104,72,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="108"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="221" Margin="10,127,0,0" VerticalAlignment="Top" Width="722">
<Label Content="Shipping Detail" HorizontalAlignment="Left" Height="27" Margin="10,10,0,0" VerticalAlignment="Top" Width="207" FontWeight="Bold"/>
<Label Content="Item:" HorizontalAlignment="Left" Height="27" Margin="10,42,0,0" VerticalAlignment="Top" Width="57"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="79,42,0,0" TextWrapping="Wrap" Text="{Binding ScanningItem.ItemNo}" VerticalAlignment="Top" Width="210"/>
<Label Content="Qty:" HorizontalAlignment="Left" Height="27" Margin="10,76,0,0" VerticalAlignment="Top" Width="57"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="79,76,0,0" TextWrapping="Wrap" Text="{Binding ScanningItem.Qty}" VerticalAlignment="Top" Width="89"/>
<Label Content="Box:" HorizontalAlignment="Left" Height="27" Margin="10,109,0,0" VerticalAlignment="Top" Width="57"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="79,109,0,0" TextWrapping="Wrap" Text="{Binding ScanningItem.Box}" VerticalAlignment="Top" Width="210"/>
<Label Content="Serial No:" HorizontalAlignment="Left" Height="27" Margin="10,142,0,0" VerticalAlignment="Top" Width="64"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="79,142,0,0" TextWrapping="Wrap" Text="{Binding ScanningItem.SerialNo}" VerticalAlignment="Top" Width="210"/>
<CheckBox Content="Item LookUp" HorizontalAlignment="Left" Margin="310,42,0,0" VerticalAlignment="Top" Width="153.42"/>
<Button Content="Add" HorizontalAlignment="Left" Margin="310,142,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="339" Margin="19,353,0,0" VerticalAlignment="Top" Width="723">
<Label Content="Scanned Items" HorizontalAlignment="Left" Height="27" Margin="10,10,0,0" VerticalAlignment="Top" Width="207" FontWeight="Bold"/>
<DataGrid HorizontalAlignment="Left" Margin="10,42,0,0" VerticalAlignment="Top"
Height="260" Width="535" AutoGenerateColumns="False" ItemsSource="{Binding ScannedItems}"
Style="{StaticResource AzureDataGrid}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ItemNo}" Header="ItemNo"/>
<DataGridTextColumn Binding="{Binding Qty}" Header="Qty"/>
<DataGridTextColumn Binding="{Binding Box}" Header="Box"/>
<DataGridTextColumn Binding="{Binding SerialNo}" Header="SerialNo"/>
</DataGrid.Columns>
</DataGrid>
<Button Content="Delete Selected" HorizontalAlignment="Left" Height="24" Margin="10,307,0,0" VerticalAlignment="Top" Width="141"/>
</Grid>
<Button Content="Exit" HorizontalAlignment="Left" Height="23" Margin="28,307,0,0" VerticalAlignment="Top" Width="151"/>
<Button Content="Send File" HorizontalAlignment="Left" Height="23" Margin="276,307,0,0" VerticalAlignment="Top" Width="151"/>
</Grid>
查看Class如下:
public partial class ShipDataCollect : MetroWindow
{
private ShipDataCollectViewModel viewModel;
public ShipDataCollect()
{
InitializeComponent();
viewModel = new ShipDataCollectViewModel();
DataContext = viewModel;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
viewModel.AddItemCommand.Execute(null);
}
}
目的:
- 添加项目,并将其显示在
DataGrid
视图中。
但遇到了以下问题。
- 添加第一个Item ->Item A {Item A, 10, Box1, SerialNo1},它将在
DataGrid
中正确显示。
- 添加第二个项目-> 项目 B {项目 B, 10, Box2, SerialNo2}。单击添加按钮后,数据网格中将显示两个项目,但它们都是项目 B。
试图多次添加相同的当前项(ScanningItem
)实例。
考虑在将前一个项目添加到集合后创建一个新项目:
private void AddItem()
{
ScannedItems.Add(ScanningItem);
ScanningItem = new Item();
}
请在 ScanningItem
属性 的值更改时引入 PropertyChanged
事件的触发,以将更改传播到 View
(数据绑定机制)。例如,使用如下支持字段将 ScanningItem
从自动实现 属性 转换为 属性(假设使用 MVVM Light):
private Item scanningItem;
public Item ScanningItem
{
get
{
return scanningItem;
}
private set
{
if (Equals(scanningItem, value))
{
return;
}
scanningItem = value;
RaisePropertyChanged("ScanningItem");
}
}
我的ViewModel
如下:
public class ShipDataCollectViewModel : ViewModelBase
{
//private ObservableCollection<Item> _scannedItems;
//private Item _scanningItem;
public ObservableCollection<Item> ScannedItems
{
get;
private set;
}
public Item ScanningItem
{
get;
private set;
}
public ShipDataCollectViewModel()
{
ScannedItems = new ObservableCollection<Item>();
ScanningItem = new Item();
AddItemCommand = new RelayCommand(AddItem, CanAddItem);
}
private RelayCommand _addItemCommand;
public RelayCommand AddItemCommand { get; private set; }
private void AddItem()
{
//var item = new Item { ItemNo = _scanningItem.ItemNo, Qty = _scanningItem.Qty, Box = _scanningItem.Box, SerialNo = _scanningItem.SerialNo };
//ScannedItems.Add(item);
//Cannot use the following code, it will overwrite all the ObservableCollection's items if exist.
ScannedItems.Add(ScanningItem);
}
private bool CanAddItem()
{
return true;
}
}
View
如下:
<Grid>
<Grid HorizontalAlignment="Left" Height="114" Margin="10,10,0,0" VerticalAlignment="Top" Width="722">
<Label Content="Customer No:" HorizontalAlignment="Left" Height="27" Margin="5,5,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="104,5,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="108"/>
<Label Content="PO No:" HorizontalAlignment="Left" Height="27" Margin="258,5,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="354,5,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="108"/>
<Label Content="SO No:" HorizontalAlignment="Left" Height="27" Margin="5,40,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="104,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="108"/>
<Label Content="Vendor:" HorizontalAlignment="Left" Height="27" Margin="255,40,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="354,40,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="108"/>
<Label Content="Invoice No:" HorizontalAlignment="Left" Height="27" Margin="5,72,0,0" VerticalAlignment="Top" Width="94"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="104,72,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="108"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="221" Margin="10,127,0,0" VerticalAlignment="Top" Width="722">
<Label Content="Shipping Detail" HorizontalAlignment="Left" Height="27" Margin="10,10,0,0" VerticalAlignment="Top" Width="207" FontWeight="Bold"/>
<Label Content="Item:" HorizontalAlignment="Left" Height="27" Margin="10,42,0,0" VerticalAlignment="Top" Width="57"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="79,42,0,0" TextWrapping="Wrap" Text="{Binding ScanningItem.ItemNo}" VerticalAlignment="Top" Width="210"/>
<Label Content="Qty:" HorizontalAlignment="Left" Height="27" Margin="10,76,0,0" VerticalAlignment="Top" Width="57"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="79,76,0,0" TextWrapping="Wrap" Text="{Binding ScanningItem.Qty}" VerticalAlignment="Top" Width="89"/>
<Label Content="Box:" HorizontalAlignment="Left" Height="27" Margin="10,109,0,0" VerticalAlignment="Top" Width="57"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="79,109,0,0" TextWrapping="Wrap" Text="{Binding ScanningItem.Box}" VerticalAlignment="Top" Width="210"/>
<Label Content="Serial No:" HorizontalAlignment="Left" Height="27" Margin="10,142,0,0" VerticalAlignment="Top" Width="64"/>
<TextBox HorizontalAlignment="Left" Height="27" Margin="79,142,0,0" TextWrapping="Wrap" Text="{Binding ScanningItem.SerialNo}" VerticalAlignment="Top" Width="210"/>
<CheckBox Content="Item LookUp" HorizontalAlignment="Left" Margin="310,42,0,0" VerticalAlignment="Top" Width="153.42"/>
<Button Content="Add" HorizontalAlignment="Left" Margin="310,142,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="339" Margin="19,353,0,0" VerticalAlignment="Top" Width="723">
<Label Content="Scanned Items" HorizontalAlignment="Left" Height="27" Margin="10,10,0,0" VerticalAlignment="Top" Width="207" FontWeight="Bold"/>
<DataGrid HorizontalAlignment="Left" Margin="10,42,0,0" VerticalAlignment="Top"
Height="260" Width="535" AutoGenerateColumns="False" ItemsSource="{Binding ScannedItems}"
Style="{StaticResource AzureDataGrid}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ItemNo}" Header="ItemNo"/>
<DataGridTextColumn Binding="{Binding Qty}" Header="Qty"/>
<DataGridTextColumn Binding="{Binding Box}" Header="Box"/>
<DataGridTextColumn Binding="{Binding SerialNo}" Header="SerialNo"/>
</DataGrid.Columns>
</DataGrid>
<Button Content="Delete Selected" HorizontalAlignment="Left" Height="24" Margin="10,307,0,0" VerticalAlignment="Top" Width="141"/>
</Grid>
<Button Content="Exit" HorizontalAlignment="Left" Height="23" Margin="28,307,0,0" VerticalAlignment="Top" Width="151"/>
<Button Content="Send File" HorizontalAlignment="Left" Height="23" Margin="276,307,0,0" VerticalAlignment="Top" Width="151"/>
</Grid>
查看Class如下:
public partial class ShipDataCollect : MetroWindow
{
private ShipDataCollectViewModel viewModel;
public ShipDataCollect()
{
InitializeComponent();
viewModel = new ShipDataCollectViewModel();
DataContext = viewModel;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
viewModel.AddItemCommand.Execute(null);
}
}
目的:
- 添加项目,并将其显示在
DataGrid
视图中。 但遇到了以下问题。 - 添加第一个Item ->Item A {Item A, 10, Box1, SerialNo1},它将在
DataGrid
中正确显示。 - 添加第二个项目-> 项目 B {项目 B, 10, Box2, SerialNo2}。单击添加按钮后,数据网格中将显示两个项目,但它们都是项目 B。
试图多次添加相同的当前项(ScanningItem
)实例。
考虑在将前一个项目添加到集合后创建一个新项目:
private void AddItem()
{
ScannedItems.Add(ScanningItem);
ScanningItem = new Item();
}
请在 ScanningItem
属性 的值更改时引入 PropertyChanged
事件的触发,以将更改传播到 View
(数据绑定机制)。例如,使用如下支持字段将 ScanningItem
从自动实现 属性 转换为 属性(假设使用 MVVM Light):
private Item scanningItem;
public Item ScanningItem
{
get
{
return scanningItem;
}
private set
{
if (Equals(scanningItem, value))
{
return;
}
scanningItem = value;
RaisePropertyChanged("ScanningItem");
}
}