Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
996 views
in Technique[技术] by (71.8m points)

wpf - How to use binding in the ListBox’s Items to the ViewModel’s properties

I have a ListBox which displays the collection of MyObjects. The collection is in the ViewModel. I want to handle a click on the button on the ListItem but have some troubles with binding. The binding in the DataTemplate works fine if the property is bound to the MyObject property. But how can I bind it to the property from the ViewModel?

The second question how I can use the information from the item in the code which handles click event. For instance, I want to print out the text from the item’s TextBox.

The code is like that:

<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?
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your ListBoxItem's will have the string items from the ObservableCollection Objects as DataContext and from there you don't have any AvatarClick RelayCommand. You can use RelativeSource in the Binding to use the DataContext from the parent ListBox instead.

For your second question, you could make use of the CommandParameter like this

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)
{
    //...
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...