Как использовать привязку в элементах ListBox к свойствам ViewModel - PullRequest
7 голосов
/ 21 декабря 2010

У меня есть ListBox, который отображает коллекцию MyObjects. Коллекция находится в ViewModel. Я хочу обработать нажатие на кнопку в ListItem, но у меня есть некоторые проблемы с привязкой. Привязка в DataTemplate работает нормально, если свойство привязано к свойству MyObject. Но как я могу привязать его к свойству из ViewModel?

Второй вопрос, как я могу использовать информацию из элемента в коде, который обрабатывает событие клика. Например, я хочу распечатать текст из TextBox элемента.

Код такой:

<Window.Resources>
    <DataTemplate x:Key="ItemTemplate">
        <Button Content="{Binding .}"
                Command="{Binding ClickCommand}" /> <!--It doesn't work-->
    </DataTemplate>

</Window.Resources>
<ListBox x:Name="ListBox"
         ItemsSource="{Binding Path=Objects}"
         IsSynchronizedWithCurrentItem="True"
         ItemTemplate="{StaticResource ItemTemplate}"/>

C #:

public partial class MainWindow : Window
{
    VM m_vm;

    public MainWindow()
    {
        m_vm = new VM();
        this.DataContext = m_vm;
        InitializeComponent();
    }
}

public class VM
{
    ObservableCollection<string> _objects;

    public ObservableCollection<string> Objects
    {
      get { return _objects; }
      set { _objects = value; }
    }

    public VM()
    {
        _objects = new ObservableCollection<string>();
        Objects.Add("A");
        Objects.Add("B");
        Objects.Add("C");
    }

    //I used relayCommand from the John Smith articles
    RelayCommand _clickCommand;
    public ICommand ClickCommand
    {
        get
        {
            if (_clickCommand == null)
            {
                _clickCommand = new RelayCommand(() => this.AvatarClick());
            }
            return _clickCommand;
        }
    }

    public void AvatarClick()
    {
        //how to get here the text from the particular item where the button was clicked?
    }
}

1 Ответ

11 голосов
/ 21 декабря 2010

Ваш ListBoxItem будет иметь строковые элементы из объектов ObservableCollection как DataContext, и оттуда у вас нет RelayCommand AvatarClick. Вы можете использовать RelativeSource в Binding, чтобы вместо этого использовать DataContext из родительского ListBox.

Для вашего второго вопроса вы можете использовать CommandParameter, как это

Xaml

<DataTemplate x:Key="ItemTemplate">
    <Button Content="{Binding .}"
            Command="{Binding DataContext.ClickCommand,
                              RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
            CommandParameter="{Binding .}"/>
</DataTemplate>

ViewModel

public ICommand ClickCommand
{
    get
    {
        if (_clickCommand == null)
        {
            _clickCommand = new RelayCommand(param => this.AvatarClick(param));
        }
        return _clickCommand;
    }
}

public void AvatarClick(object param)
{
    //...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...