繁体   English   中英

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

[英]how to set command binding For All controls in wpf

如何为wpf中没有的控件设置命令绑定? 例如如何在listBox项目中设置命令? 或如何在treeView项目中设置命令?

                            <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>

你到底是什么意思 Command属性只是Button_Click属性的“绑定方式”。 如果您想拥有一个ListBoxItem,可以在其中单击并调用方法,则只需执行以下操作:

    <Grid>
        <ListBox>
            <ListBoxItem>
                <Button Content="Test"
                        Command="{Binding}">
                </Button>
            </ListBoxItem>
        </ListBox>
    </Grid>

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

MainWindow.xaml

<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

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

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

<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
第三种选择是使用附加属性将ICommand附加到每个ListBoxItem或任何其他Control (基本上附加到任何DependencyObject )。
第四个选项是通过扩展ListBoxItem并实现ICommandSource来创建自定义项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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