首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在wpf中为所有控件设置命令绑定

如何在wpf中为所有控件设置命令绑定
EN

Stack Overflow用户
提问于 2019-08-26 13:52:02
回答 2查看 406关注 0票数 0

如何为wpf中不可能的控件设置命令绑定?例如如何在listBox项目中设置命令?或者如何在treeView项目中设置命令?

代码语言:javascript
复制
                            <ListBox  Style="{StaticResource MaterialDesignToolToggleListBox}"  ItemContainerStyle="{DynamicResource _ListBoxItemStyle}" >
                            <ListBoxItem >
                                <materialDesign:PackIcon VerticalAlignment="Center" HorizontalAlignment="Center" Kind="MicrosoftWindows" />
                            </ListBoxItem>
                            <ListBoxItem>
                                <materialDesign:PackIcon Kind="Games" />
                            </ListBoxItem>
                            <ListBoxItem IsSelected="True">
                                <materialDesign:PackIcon Kind="Video"  />
                            </ListBoxItem>
                            <ListBoxItem>
                                <materialDesign:PackIcon Kind="Image" />
                            </ListBoxItem>
                        </ListBox>
EN

回答 2

Stack Overflow用户

发布于 2019-08-26 16:58:19

ListBoxItem没有实现ICommandSource。这就是它不能执行ICommand的原因。要解决此问题,您可以覆盖ListBoxItem的模板,并使用Button作为内容宿主:

MainWindow.xaml

代码语言:javascript
复制
<Window>
  <Window.DataContext>
    <ViewModel />
  </Window.DataContext>

  <ListBox>
      <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="ListBoxItem">
                <Button Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Padding="{TemplateBinding Padding}"
                        Content="{TemplateBinding Content}"
                        Command="{Binding MyCommand}"/>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </ListBox.ItemContainerStyle>

      <ListBoxItem>
        <materialDesign:PackIcon VerticalAlignment="Center"
                                 HorizontalAlignment="Center"
                                 Kind="MicrosoftWindows" />
  </ListBox>
</Window>

如果需要为每个项分配单独的命令,则需要定义一个带有ButtonListBox.ItemTemplate作为内容主机,它将Button.Command绑定到数据项的ICommand属性。

ViewModel.cs

代码语言:javascript
复制
class LabelData : INotifyPropertyChanged
{
  private string label;
  public string Label
  {
    get => this.label;
    set
    {
      this.label = value;
      OnPropertyChanged();
    }
  }

  private ICommand myCommand;
  public ICommand MyCommand
  {
    get => this.myCommand;
    set
    {
      this.myCommand = value;
      OnPropertyChanged();
    }
  }

  // Constructor
  // Initialize the data binding source of the ListBoxItems
  public void LabelData(string label)
  {
    this.Label = label;
  }

  public event PropertyChangedEventHandler PropertyChanged;
  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

ViewModel.cs

代码语言:javascript
复制
class ViewModel : INotifyPropertyChanged
{
  private ObservableCollection<LabelData> labels;
  public ObservableCollection<LabelData> Labels
  {
    get => this.labels;
    set
    {
      this.labels = value;
      OnPropertyChanged();
    }
  }

  // Constructor
  // Initialize the data binding source of the ListBox
  public void ViewModel()
  {
    this.Labels = new ObservableCollection<LabelData>() 
    { 
      new LabelData("MicrosoftWindows") { MyCommand = SomeCommand},
      new LabelData("Games") { MyCommand = SomeOtherCommand},
      new LabelData("Video") { MyCommand = SomeOtherCommand},
      new LabelData("Image") { MyCommand = SomeCommand}
    };
  }

  public event PropertyChangedEventHandler PropertyChanged;
  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

MainWindow.xaml

代码语言:javascript
复制
<Window>
  <Window.DataContext>
    <ViewModel />
  </Window.DataContext>

  <ListBox ItemsSource="{Binding Labels}">
      <ListBox.ItemTemplate>
        <DataTemplate DataType="LabelData">
          <Button Command="{Binding MyCommand}">
            <Button.Content>
              <materialDesign:PackIcon Kind="{Binding Label}" />
            </Button.Content>
          </Button>
        </DataTemplate>
      </ListBox.ItemTemplate>
  </ListBox>
</Window>

这两个选项也适用于TreeView

第三种选择是使用Attached属性将ICommand附加到每个ListBoxItem或任何其他Control (基本上附加到任何DependencyObject)。

第四种选择是通过扩展ListBoxItem和实现ICommandSource来创建自定义项。

票数 1
EN

Stack Overflow用户

发布于 2019-08-26 14:02:37

你到底是什么意思?Command属性只是Button_Click属性的“绑定方式”。如果你想有一个ListBoxItem,你可以点击并调用一个方法,那么只需使用下面的代码:

代码语言:javascript
复制
    <Grid>
        <ListBox>
            <ListBoxItem>
                <Button Content="Test"
                        Command="{Binding}">
                </Button>
            </ListBoxItem>
        </ListBox>
    </Grid>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57652423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档