【问题标题】:Dynamically generated TextBox and Input Bindings : Where to put the Commands动态生成的文本框和输入绑定:放置命令的位置
【发布时间】:2012-03-13 13:32:06
【问题描述】:

我正在像这样在 ItemsControl 中生成一个文本框列表:

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

在输入绑定中,我想访问一个在 ViewModel 级别可用的命令,与 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 的解决方法,可以访问我需要的地方不可用的属性,但我想一定有比这更好的方法...

任何可以帮助我的人:因为让那段痛苦变得不那么痛苦而感到被拥抱;-)

【问题讨论】:

  • 您尝试过使用{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=Name} 之类的东西吗?将 ItemsControl 替换为具有包含所需命令的 DataContext 的父控件类型。
  • 是的,这是我发现的一件事:{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path =DataContext.ResetInputCommand}。它不是很漂亮,但它确实有效
  • 由于还没有其他回复:您可以将其发布为一个,所以我可以将其标记为答案

标签: wpf binding mvvm command


【解决方案1】:

使用类似的东西

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

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

【讨论】:

    【解决方案2】:

    为什么不在您的基础视图模型类中有一个父属性,该属性将是一个视图模型基础。然后在您的 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 中的绑定是动态的,所以它不需要是父对象的具体类型。

    【讨论】:

    • 感谢您的提示,但我不打算通过创建导航属性来进一步膨胀我的 ViewModel。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    相关资源
    最近更新 更多