动态生成的TextBox和输入绑定:将命令放在何处

时间:2012-03-13 13:32:07

标签: wpf binding mvvm command

我正在ItemsControl中生成一个TextBoxes列表,如下所示:

<ItemsControl ItemsSource="{Binding CurrentCandidate.Properties}">
 <ItemsControl.ItemTemplate>
  <DataTemplate>
    <DockPanel>
      <TextBlock DockPanel.Dock="Top" Text="{Binding DisplayName}" />
      <Border DockPanel.Dock="Top">
        <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}">
          <TextBox.InputBindings>
            <KeyBinding Command="{?}" CommandParameter={?} Key="PgUp" />
            <KeyBinding Command="{?}" CommandParameter={?} Key="Enter" />
          </TextBox.InputBindings>
     </TextBox>
       </Border>
     </DockPanel>
    </DataTemplate>
 </ItemsControl.ItemTemplate>
</ItemsControl>

在input-Bindings中,我想访问ViewModel-Level中可用的Command,与ItemsSource处于同一级别。为了从ItemTemplate中访问它,我到目前为止使用了以下解决方法:

    <TextBlock x:Name="tbCurrentCandidate"
               Tag="{Binding Path=CurrentCandidate}"
               Visibility="Hidden"></TextBlock>
    <TextBlock x:Name="tbReset"
               Tag="{Binding Path=ResetInputCommand}"
               Visibility="Hidden"></TextBlock>
    <TextBlock x:Name="tbValidate"
               Tag="{Binding Path=ValidateCommand}"
               Visibility="Hidden"></TextBlock>
<TextBox.InputBindings>
  <KeyBinding Command="{Binding ElementName=tbReset, Path=Tag}"
   CommandParameter="{Binding ElementName=tbCurrentCandidate, Path=Tag}"
   Key="PgUp" />
  <KeyBinding Command="{Binding ElementName=tbValidate, Path=Tag}"
   CommandParameter="{Binding ElementName=tbCurrentCandidate, Path=Tag}"
   Key="Enter" />
</TextBox.InputBindings>

这是一个类似HTML-Hidden-Field的解决方法,用于访问我需要的地方不可用的属性,但我想必须有一个更好的方法...

任何可以帮助我的人:感到拥抱让这段苦难变得更加悲惨; - )

2 个答案:

答案 0 :(得分:0)

为什么在基础视图模型类中没有父属性,它将是视图模型库。然后在您的XAML中,您可以简单地绑定到Parent.TheCommand。

public class ViewModelBase : INotifyPropertyChanged
{
    /// <summary>
    /// The model's parent item.
    /// </summary>
    protected ViewModelBase _parent;

    /// <summary>
    /// Default Constructor.
    /// </summary>
    /// <param name="parent">Optional Parameter, The model's parent model. </param>
    public ViewModelBase(ViewModelBase parent = null)
    {
        _parent = parent;
    }

    /// <summary>
    /// The model's parent model.
    /// </summary>
    public ViewModelBase Parent
    {
        get { return _parent; }
    }

    //All other common properties and methods.
 }

因为XAML中的绑定是动态的,所以它不需要是父类的具体类型。

答案 1 :(得分:0)

使用类似

的内容
{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=Name}

ItemsControl替换为包含所需命令的DataContext的父控件类型。