简体   繁体   中英

WPF Bind command property from selected item in observablecollection

I am using Listview having datasource as observablecollection <empclass>

My overall class structure is like

Class empclass
{ 
 command = new RelayCommand(myfunction, true);

 private int _abc;
 public int abc
  {
    get { return _abc;}
    set { _abc = value;
    onpropertychanged("abc")
   }

 private int _pqr;
 public int pqr
  {
    get { return _pqr;}
    set { _pqr = value;
    onpropertychanged("pqr")
  }



 public void myfunction()
 {
   messagebox.show((abc+pqr).Tostring());
 }
}

i have a separate button, where on click i want to invoke command of selected item to show addition of abc and pqr on respected values present in that object.

It would be great If you could help me with small code example.

Thanks Ashpak

I'm assuming you have a ListView named lv :

<ListView Name="lv" ... </ListView>

Then you can bind to the SelectedItem of that ListView and use the item's command property.

<Button Command="{Binding ElementName=lv, Path=SelectedItem.command}">Button Text</Button>

Note that for this to work you have to have a public property command, eg:

Class empclass
{ 
    public RelayCommand command {get;set;}
    ...
}

Try this: 1. XAML code:

<Window x:Class="SoButtonBindingHelpAttempt.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:soButtonBindingHelpAttempt="clr-namespace:SoButtonBindingHelpAttempt"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <soButtonBindingHelpAttempt:MainViewModel/>
</Window.DataContext>
<Grid>
    <ListBox ItemsSource="{Binding ObservableCollection}">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate DataType="{x:Type soButtonBindingHelpAttempt:Empclass}">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="120"></ColumnDefinition>
                                    <ColumnDefinition Width="120"></ColumnDefinition>
                                    <ColumnDefinition Width="120"></ColumnDefinition>
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" Text="{Binding abc, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></TextBlock>
                                <TextBlock Grid.Column="1"  Text="{Binding pqr, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></TextBlock>
                                <Button    Grid.Column="2"  Command="{Binding Command}" Content="Press me!"></Button>
                            </Grid>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
</Grid></Window>

2. ViewModel code Model code:

    public class MainViewModel:BaseObservableObject
{
    public MainViewModel()
    {
        ObservableCollection = new ObservableCollection<Empclass>(new List<Empclass>
        {
            new Empclass{abc=2, pqr = 3},
            new Empclass{abc=5, pqr = 7},
            new Empclass{abc=11, pqr = 13},
            new Empclass{abc=17, pqr = 19}
        });
    }
    public ObservableCollection<Empclass> ObservableCollection { get; set; }
}

public class Empclass : BaseObservableObject
{
    private ICommand _command;
    private int _abc;
    private int _pqr;

    public ICommand Command
    {
        get { return _command ?? (_command = new RelayCommand(myfunction)); }
    }

    public int abc
    {
        get { return _abc; }
        set
        {
            _abc = value;
            OnPropertyChanged("abc");
        }
    }


    public int pqr
    {
        get { return _pqr; }
        set
        {
            _pqr = value;
            OnPropertyChanged("pqr");
        }
    }


    private void myfunction()
    {
        //add you command logic here
        var temp = pqr;
        pqr = abc;
        abc = temp;
    }
}

3. MVVM parts implementation:

    public class BaseObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
    {
        var propName = ((MemberExpression)raiser.Body).Member.Name;
        OnPropertyChanged(propName);
    }

    protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
    {
        if (!EqualityComparer<T>.Default.Equals(field, value))
        {
            field = value;
            OnPropertyChanged(name);
            return true;
        }
        return false;
    }
}

public class RelayCommand<T> : ICommand
{
    readonly Action<T> _execute;
    readonly Func<T, bool> _canExecute;

    public event EventHandler CanExecuteChanged;

    public RelayCommand(Action<T> execute, Func<T, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public void RefreshCommand()
    {
        var cec = CanExecuteChanged;
        if (cec != null)
            cec(this, EventArgs.Empty);
    }

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null) return true;
        return _canExecute((T)parameter);
    }

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

public class RelayCommand : RelayCommand<object>
{
    public RelayCommand(Action execute, Func<bool> canExecute = null)
        : base(_ => execute(),
            _ => canExecute == null || canExecute())
    {

    }
}

4. Look like this: 看起来像

Regards

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM