我在WPF ListView中显示项目列表,这些项目包含数量,订单代码和描述。这些列绑定到View Model中保存的ObservableCollection中的字段。这一切都非常标准,并且按预期工作。但是,在ListView的数量列中,我添加了两个按钮+和 - ,这个想法是当按下它们时,数量的值会递增或递减。问题是因为这些按钮没有绑定到ObservableCollection中的字段,所以我无法从列表视图中按下的按钮到ObservableCollection中的记录获得链接。我已经尝试在ListView中选择项目,但是按下时按钮被选中而不是ListView项目,我还在按下按钮时捕获了鼠标指针下方的项目,但可以使用键盘按下它。
我觉得必须有一种(简单!)的方法,但我找不到它。
这是XAML:
<ListViewName="AccessoriesContent" >
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Select">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Name="QuantityStack">
<Button Name="SubtractAccessoryButton" Command="vx:DataCommands.SubtractAccessory" Content="-" />
<TextBox Name="QuantityTextBox" Text="{Binding Quantity, Mode=TwoWay}" />
<Button Name="AddAccessoryButton" Command="vx:DataCommands.AddAccessory" Content="+" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Order Code" DisplayMemberBinding="{Binding OrderCode}" />
<GridViewColumn Header="Description" DisplayMemberBinding="{Binding Description}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
背后的代码:
public MainWindow()
{
//CommandBindings.Add(
InitializeComponent();
AccessoryVM = new AccessoryViewModel();
AccessoriesContent.ItemsSource = AccessoryVM.AccessoryCollection;
}
ViewModel:
class AccessoryViewModel
{
ObservableCollection<AccessoryData> _AccessoryCollection =
new ObservableCollection<AccessoryData>();
public ObservableCollection<AccessoryData> AccessoryCollection
{ get { return _AccessoryCollection; } }
public void PopulateAccessories(string order_code)
{
// Read the data and populate AccessoryCollection
}
}
public class AccessoryData : INotifyPropertyChanged
{
private int _quantity;
public int Quantity
{
get { return _quantity; }
set
{
this._quantity = value;
Notify("Quantity");
}
}
public string OrderCode { get; set; }
public string Description { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void Notify(string propName)
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
除此之外,我有两个由按钮触发的方法SubtractAccessory和AddAccessory,但我还没有用任何可行的方法填充它们。
答案 0 :(得分:1)
您似乎没有发布您使用的命令。
无论如何,如果您使用命令,您可以使用视图模型上存在的实例命令(然后您需要将命令绑定到DataContext
上的命令属性),因此可以访问{ {1}}或者您可以将视图模型作为Quantity
传递,只需将其设置为CommandParameter
,然后在命令中您可以将参数转换为VM并更改{Binding}
。
(如果您要使用Quantity
事件,则可以将Click
转换为sender
并将其Button
强制转换为VM
答案 1 :(得分:1)
另一种选择是创建一个RelayCommand(参见here)。在此模型中,您将在每个项目上创建ICommand属性。然后,将此属性设置为新的RelayCommand,该RelayCommand接受在激活该命令时要运行的委托。所以这可能是AccessoryData上的QuantityUp方法和QuantityDown方法。一旦你有了你的ICommand属性,就可以像这样绑定它,其中QuantityUpCommand是你的ICommand属性。
<GridViewColumn Header="" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Height="15" Width="15" Content="+" Command="{Binding QuantityUpCommand}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
AccessoryData看起来像这样
private RelayCommand _quantityUpCommand;
public ICommand QuantityUpCommand
{
get
{
if (_quantityUpCommand == null)
{
_quantityUpCommand = new RelayCommand(QuantityUp);
}
return _quantityUpCommand;
}
}
public void QuantityUp(object obj)
{
Quantity++;
}
RelayCommand看起来像这样:
public class RelayCommand: ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}
答案 2 :(得分:0)
您可以通过唯一标识当前项目的按钮上的CommandParameter
传递当前项目。因此,在执行命令时,您知道您正在谈论的是什么项目。如果您在项目中找不到唯一的标记,您甚至可以传递整个项目!
<Button Name="AddAccessoryButton" Command="vx:DataCommands.AddAccessory" CommandParameter="{Binding}" Content="+" />