Динамически генерируемые привязки TextBox и ввода: куда поместить команды - PullRequest
0 голосов
/ 13 марта 2012

Я создаю список TextBox в рамках 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>

В привязках ввода я хочу получить доступ к команде, доступной на уровне представления модели, на том же уровне, что и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, для доступа к свойствам, которые недоступныгде я нуждаюсь в них, но я полагаю, что должен быть лучший способ, чем этот ...

Любой, кто может мне помочь: чувствую себя обиженным для того, чтобы сделать этот кусочек страдания менее жалким; -)

Ответы [ 2 ]

0 голосов
/ 14 марта 2012

Используйте что-то вроде

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

Заменить ItemsControl на родительский тип управления, который имеет DataContext, содержащий нужные команды.

0 голосов
/ 13 марта 2012

Почему бы не в вашем базовом классе модели представления иметь родительское свойство, которое будет базой модели представления. Затем в вашем 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 является динамической, ей не обязательно должен быть конкретный тип родителя.

...