1

我正在使用股票交易者参考实现的示例代码。

http://prism4.googlecode.com/svn/trunk/Prism4/

PositionSummaryView.xaml 中有一个股票列表。在股票列表中,我添加了一个带有显示股票名称的文本框的 GridViewColumn。当用户通过使用行为 ReturnCommandBehavior 按下回车键时,我尝试在 ViewModel 中调用命令。

当我在文本框中按 Enter 时,该命令未命中。当我在列表之外有相同的文本框时,命令被命中。

这适用于 ListView

<TextBox Grid.Column="0"  Text="test"    Infrastructure:ReturnKey.Command="{Binding Path=UpdateTickerSymbolCommand}"  ></TextBox>

这是我在 TextBox 中尝试的绑定,但没有一个有效:

 <TextBox Grid.Column="0"  Text="{Binding  Path=TickerSymbol}"  
                                  Infrastructure:ReturnKey.Command="{Binding Path=UpdateTickerSymbolCommand, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}"  ></TextBox>

第二次尝试

  <TextBox Grid.Column="0"  Text="{Binding  Path=TickerSymbol}"   Infrastructure:ReturnKey.Command="{Binding ElementName=root,Path= UpdateTickerSymbolCommand}" ></TextBox>

这是视图模型:

using System.ComponentModel.Composition;
using System.Windows.Input;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.ViewModel;
using StockTraderRI.Infrastructure;
using StockTraderRI.Modules.Position.Controllers;
using Microsoft.Practices.Prism.Commands;

namespace StockTraderRI.Modules.Position.PositionSummary
{
    [Export(typeof(IPositionSummaryViewModel))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class PositionSummaryViewModel : NotificationObject, IPositionSummaryViewModel
    {
        private PositionSummaryItem currentPositionSummaryItem;

        private readonly IEventAggregator eventAggregator;

        public IObservablePosition Position { get; private set; }


        private ICommand updateTickerSymbolCommand;

        public ICommand UpdateTickerSymbolCommand { get { return this.updateTickerSymbolCommand; } }

        [ImportingConstructor]
        public PositionSummaryViewModel(IOrdersController ordersController, IEventAggregator eventAggregator, IObservablePosition observablePosition)
        {
            this.eventAggregator = eventAggregator;
            this.Position = observablePosition;

            BuyCommand = ordersController.BuyCommand;
            SellCommand = ordersController.SellCommand;
            updateTickerSymbolCommand = new DelegateCommand<string>(this.UpdateTickerSymbol); ;

            this.CurrentPositionSummaryItem = new PositionSummaryItem("FAKEINDEX", 0, 0, 0);
        }

        private void UpdateTickerSymbol(string tickerSymbol)
        {

        }



        public ICommand BuyCommand { get; private set; }

        public ICommand SellCommand { get; private set; }

        public string HeaderInfo
        {
            get { return "POSITION"; }
        }

        public PositionSummaryItem CurrentPositionSummaryItem
        {
            get { return currentPositionSummaryItem; }
            set
            {
                if (currentPositionSummaryItem != value)
                {
                    currentPositionSummaryItem = value;
                    this.RaisePropertyChanged(() => this.CurrentPositionSummaryItem);
                    if (currentPositionSummaryItem != null)
                    {
                        eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Publish(
                            CurrentPositionSummaryItem.TickerSymbol);
                    }
                }
            }
        }
    }
}

按下回车键时我需要点击 UpdateTickerSymbol 什么?

编辑

我现在看到我误解了

Binding ElementName=root

在一些示例代码中。我认为 root 是一个关键字,但它是必须赋予视图中的父控件的键

这就是为什么我用

  <StackPanel x:Name="LayoutRoot" >

现在在父控件中

<TextBox Grid.Column="0"  Text="{Binding  Path=TickerSymbol}"   Infrastructure:ReturnKey.Command="{Binding ElementName=LayoutRoot, Path=UpdateTickerSymbolCommand}" ></TextBox>

对于文本框,但该命令仍未命中。

我还在示例中使用 Button 尝试了上述语法,并且它有效

<Button Grid.Column="0" Command="{Binding Path=DataContext.BuyCommand, ElementName=LayoutRoot}" CommandParameter="{Binding Path=TickerSymbol}" AutomationProperties.AutomationId="ActionsBuyButton" Template="{StaticResource AddButtonTemplate}"  Cursor="Hand" Width="30" />
4

2 回答 2

1

您可以简单地使用 TextBox.InputBindings 并且希望在文本上使用 Mode=TwoWay 和 UpdateSourceTrigger=PropertyChanged。

.xaml

    <ListView HorizontalAlignment="Stretch" 
              Height="Auto" 
              ItemsSource="{Binding Collection}"
              VerticalAlignment="Stretch" 
              Width="Auto">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBox Width="100" 
                         Text="{Binding MyText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                    <TextBox.InputBindings>
                        <KeyBinding Key="Enter" Command="{Binding MyCommand}" />
                    </TextBox.InputBindings>
                </TextBox>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

您的数据模型将是

。CS

public class DataModel : INotifyPropertyChanged
{
    private string m_myText;
    public string MyText
    {
        get { return m_myText; }
        set 
        { 
            m_myText = value;
            OnPropertyChanged("MyText");
        }
    }

    public ICommand MyCommand { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

视图模型上的集合

视图模型.cs

Collection = new ObservableCollection<DataModel> { new DataModel() { MyText = String.Empty, MyCommand = m_myCommand } };
于 2012-10-16T03:23:30.047 回答
1

我下载了源码。文本框似乎消失了。将 TextBox 的命令更改为 DataContext.BuyCommand “修复”了“问题”。命令“UpdateTickerSymbolCommand”似乎也不再可用,所以我也无法测试它。当前源也没有对 StackPanel (LayoutRoot) 的引用,所以我也无法跟踪。我认为这里的关键问题是没有正确设置命令。

于 2012-10-22T17:54:19.447 回答