WPF 从 observablecollection 中的选定项绑定命令 属性

WPF Bind command property from selected item in observablecollection

我正在使用将数据源作为 observablecollection 的 Listview<empclass>

我的整体class结构是这样的

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());
 }
}

我有一个单独的按钮,单击该按钮我想调用所选项目的命令以显示对该对象中存在的相关值添加 abc 和 pqr。

如果你能帮我写一个小代码示例就太好了。

谢谢 阿什帕克

我假设您有一个名为 lv:

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

然后你可以绑定到 ListViewSelectedItem 并使用项目的 command 属性.

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

请注意,要使其正常工作,您必须有一个 public property 命令,例如:

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

试试这个: 1. XAML 代码:

<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代码模型代码:

    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 部件实现:

    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。看起来像这样:

此致