0

Hi i want to bind button with other listView.Item. What i want is to have something like we have on stackoverflow. But i have problem with having increasing/decreasing value. I have event Click but i dont knew how to get corresponding item on list and increase/decrease value. List view. Concept model

<DataTemplate>
    <StackPanel Orientation="Vertical">
        <StackPanel Orientation="Horizontal">
            <Label Width="706" Height="75" Content="{Binding feedback}"/>
            <StackPanel Orientation="Vertical">
                <Button Name="buttonUp" Content="^" Command="{Binding upVoteCommand}" />
                <Label HorizontalContentAlignment="Center" Width="50" Content="{Binding grade}"/>
                <Button Name="buttonDown" Content="v" Command="{Binding upVoteCommand}"/>
            </StackPanel>
        </StackPanel>
        <Label>-</Label>
    </StackPanel >

EDIT

class A {
    public string feedback {
        get;
        set;
    }
    public int grade {
        get;
        set;
    }

    private ICommand _upVoteCommand;
    private ICommand _downVoteCommand;
    public ICommand upVoteCommand {
        get {
            return _upVoteCommand;
        }
        set {
            _upVoteCommand = value;
        }
    }
    public ICommand downVoteCommand {
        get {
            return _downVoteCommand;
        }
        set {
            _downVoteCommand = value;
        }
    }
}

EDIT I used this button.Commmand but still it not working. I dont knew what to do with this commands.

Luffy
  • 677
  • 1
  • 6
  • 19
  • in the same way you bind `feedback` bind `Button.Command` to `upVote` and `downVote` commands in your item and increase/decrease `feedback` there – dkozl Jul 03 '13 at 12:02
  • ok i will try thx. I didnt knew about Command property. – Luffy Jul 03 '13 at 12:04
  • do you use some MVVM framework or have implementation of `ICommand`? – dkozl Jul 03 '13 at 12:05
  • nope.I am learing how things works in wpf. I would like to learn MVVM, but after i understand wpf a litle bit. – Luffy Jul 03 '13 at 12:07
  • What do your onClick code look like, and while we're at it, have you set the datacontext? – Nathan Cooper Jul 03 '13 at 12:07
  • To be honest, learning WPF and learning MVVM together is much easier than learning each on their own. There are no real difficulties in the concept of MVVM but it makes understanding databinding and the concept of a DataContext much much easier imho. – dowhilefor Jul 03 '13 at 12:09

2 Answers2

2

First you'll need your implementation of ICommand so you can bind commands from view model to controls, something like this:

public class RelayCommand : ICommand
{
  private readonly Action<object> _execute;
  private readonly Predicate<object> _canExecute;

  public RelayCommand(Action<object> execute) : this(execute, null) { }

  public RelayCommand(Action<object> execute, Predicate<object> canExecute)
  {
      if (execute == null) throw new ArgumentNullException("execute");
      _execute = execute; 
      _canExecute = canExecute;
  }

  public bool CanExecute(object parameter)
  {
      return _canExecute == null ? true : _canExecute(parameter);
  }

  public event EventHandler CanExecuteChanged
  {
      add { CommandManager.RequerySuggested += value; }
      remove { CommandManager.RequerySuggested -= value; }
  }

  public void Execute(object parameter) { _execute(parameter); }
}

then in you class, where you publish Feedback, you'll need to publish 2 new RelayCommand for up/down vote that will modify Feedback property accordingly. Below you can find my class that I used for tests:

public class MyClass : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;

  private void OnPropertyChanged(string propertyName)
  {
      if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  }

  private int _feedback = 0;

  public int Feedback
  {
      get { return _feedback; }
      set
      {
          if (_feedback == value) return;
          _feedback = value;
          OnPropertyChanged("Feedback");
      }
  }

  private RelayCommand _upVoteCmd;

  public ICommand UpVoteCmd
  {
      get
      {
          if (_upVoteCmd == null) _upVoteCmd = new RelayCommand(o => Feedback += 1);
          return _upVoteCmd;
      }
  }

  private RelayCommand _downVoteCmd;

  public ICommand DownVoteCmd
  {
      get
      {
          if (_downVoteCmd == null) _downVoteCmd = new RelayCommand(o => Feedback -= 1);
          return _downVoteCmd;
      }
  }

}

and then you bind your new commands in XAML like this:

<Button Content="+" Command="{Binding Path=UpVoteCmd}"/>
<TextBlock Text="{Binding Path=Feedback}"/>            
<Button Content="-" Command="{Binding Path=DownVoteCmd}"/>
dkozl
  • 32,814
  • 8
  • 87
  • 89
1

RoutedEvents don't work so easily with DataTemplates, because you don't have a code behind where your event code could be placed. While there are ways to do that, you can just use Commands to do the same. In the view model for each item (i just assume you use MVVM) create properties called UpVoteCommand and DownVoteCommand of type ICommand, DelegateCommands are quiet handy for this. Bind them to the Command property and remove the Click handler in your DataTemplate.

[EDIT]

Small example of a possible Viewmodel for one entry in the list, which can be up or downvoted.

class MyEntryViewModel : INotifyPropertyChanged
{
    public MyEntryViewModel()
    {
        UpVoteCommand = new DelegateCommand(OnUpVoteCommand);
    }
    public int Votes 
    {
        get {return mVotes;}
        set {mVotes = value; RaiseProperty("Votes");}
    }

    public ICommand UpVoteCommand 
    {
        get; private set;
    }

    void OnUpVoteCommand(object aParameter)
    {
        Votes++;
    }
}

i left the implementation of INotifyPropertyChanged and the down vote command for sake of simplicity.

Community
  • 1
  • 1
dowhilefor
  • 10,971
  • 3
  • 28
  • 45
  • I do that but i dont knew how to increase decrease value using ICommand. I tried in getter setter put +-1, but i doesnt work. – Luffy Jul 03 '13 at 12:21
  • @Luffy check my answer, i added a small code sample. In short, your edit with the class shows that you never initialize the ICommand to a real instance. – dowhilefor Jul 03 '13 at 12:26