Wpf 如何将命令行为附加到ListView中的文本框?

Wpf 如何将命令行为附加到ListView中的文本框?,wpf,mvvm,prism,prism-4,Wpf,Mvvm,Prism,Prism 4,我正在使用股票交易员参考实现的示例代码 PositionSummaryView.xaml中有一个库存列表。在股票列表中,我添加了一个GridViewColumn,其中包含一个显示股票名称的文本框。当用户使用行为ReturnCommandBehavior点击enterkey时,我尝试在ViewModel中调用一个命令 当我在文本框中按enter键时,该命令未被点击。当我在列表外有相同的文本框时,该命令被点击 这在ListView之外工作 <TextBox Grid.Column="0"

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

PositionSummaryView.xaml中有一个库存列表。在股票列表中,我添加了一个GridViewColumn,其中包含一个显示股票名称的文本框。当用户使用行为ReturnCommandBehavior点击enterkey时,我尝试在ViewModel中调用一个命令

当我在文本框中按enter键时,该命令未被点击。当我在列表外有相同的文本框时,该命令被点击

这在ListView之外工作

<TextBox Grid.Column="0"  Text="test"    Infrastructure:ReturnKey.Command="{Binding Path=UpdateTickerSymbolCommand}"  ></TextBox>
在一些示例代码中。我认为root是一个关键字,但它是必须在视图中提供给父控件的关键字

这就是为什么我用

  <StackPanel x:Name="LayoutRoot" >

在父控件中

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

用于文本框,但命令仍然未命中

我还用示例中的一个按钮尝试了上述语法,它起了作用

<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" />

您只需使用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>
视图模型上的集合

ViewModel.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));
        }
    }
}
Collection = new ObservableCollection<DataModel> { new DataModel() { MyText = String.Empty, MyCommand = m_myCommand } };
Collection=newobserveCollection{newdatamodel(){MyText=String.Empty,MyCommand=m_MyCommand};

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

这是可行的,但我必须了解prism中的附加行为是如何工作的。我刚刚找到了解决方案,而且很简单。但是我想让你赢得200分!只需查看文本框的编辑代码。特别是在基础设施方面:ReturnKey.Command。
<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" />
    <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>
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));
        }
    }
}
Collection = new ObservableCollection<DataModel> { new DataModel() { MyText = String.Empty, MyCommand = m_myCommand } };