与ItemsSource的WPF DataBinding交互

本文关键字:DataBinding 交互 WPF ItemsSource | 更新日期: 2023-09-27 18:25:38

在我的ListBox中,我有一些控件需要绑定到ItemsSource和Viewmodel中的属性。您可以看到的按钮需要同时执行这两项操作。我似乎唯一能做到这一点的方法是非常丑陋的(请参阅绑定到视图视图模型的IsEnabled属性)。我想知道最好的方法是什么。

EDIT:为了澄清,我想将IsEnabled属性绑定到CanRemove。

<Button IsEnabled="{Binding CanRemove}"></Button>

不起作用

感谢

XAML

<ListBox x:Name="songListBox" ItemsSource="{Binding SongList, Mode=TwoWay}" SelectedItem="{Binding SelectedSongAndNumber, Mode=TwoWay}" SelectionChanged="songListBox_SelectionChanged" Tag="{Binding OperationState, Mode=TwoWay}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                .......
                <Label Grid.Column="1" Width="200" Height="40" Content="{Binding Number, Mode=TwoWay}"/>
                <TextBox Grid.Column="3" Width="200" Height="40" Text="{Binding Name, Mode=TwoWay}"/>
                <Button Grid.Column="5" x:Name="btnMerge" Click="btnMerge_Click" Content="{Binding Tag, Converter={StaticResource ButtonConverter}, ElementName=songListBox}" IsEnabled="{Binding DataContext,Converter={StaticResource EnableConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:AlbumTrackAssociationView}}}">
                    <Button.Visibility>
                        <MultiBinding Converter="{StaticResource B2V}">
                            <Binding Path="Number"/>
                            <Binding ElementName="songListBox"/>
                        </MultiBinding>
                    </Button.Visibility>
                </Button>
                <Button Grid.Column="7" x:Name="btnDelete" Click="btnDelete_Click" IsEnabled="{Binding DataContext, Converter={StaticResource EnableConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:AlbumTrackAssociationView}}}">Delete
                    <Button.Visibility>
                        <MultiBinding Converter="{StaticResource B2V}">
                            <Binding Path="Number"/>
                            <Binding ElementName="songListBox"/>
                        </MultiBinding>
                    </Button.Visibility>
                </Button>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

ViewModel

public class AlbumTrackAssociationViewModel : ViewModelBase
{
    public class SongAndNumber : ViewModelBase
    {
        private string number;
        public string Number
        {
            get { return number; }
            set { 
                number = value;
                RaisePropertyChanged("Number");
            }
        }
        private string name;
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                RaisePropertyChanged("Name");
            }
        }
    }
    private int _numberOfSongs { get; set; }
    public bool CanRemove
    {
        get { return SongList != null && (SongList.Count <= _numberOfSongs ? false : true); }
    }
    public ObservableCollection<SongAndNumber> SongList { get; set; }
}

转换器

public class ItemButtonConverter : IValueConverter
{
    public object Convert(object value, Type TargetType, object parameter, CultureInfo culture)
    {
        AlbumTrackAssociationViewModel vm = (AlbumTrackAssociationViewModel)value;
        return vm.CanRemove;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

与ItemsSource的WPF DataBinding交互

当您可以使用RelativeSource标记扩展直接访问ViewModel时,根本不需要转换器。这应该有效:

<Button IsEnabled="{Binding DataContext.CanRemove,
              RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}"/>

由于ListBox的DataContext指向viewModel实例,所以上面发布的代码将起作用。

当您执行mvvm并想要使用按钮时,您应该使用DelegateCommand或RelayCommand。如果你使用它,那么你只需要正确地实现ICommand(CanExecute!)-绑定到按钮的命令将为你处理IsEnabled。

  <Button Command="{Binding MyRemoveCommand}"></Button>

cs。

  public ICommand MyRemoveCommand {get;set;}
  this.MyRemoveCommand = new DelegateCommand(this.RemoveCommandExecute, this.CanRemoveCommandExecute);
  private bool CanRemoveCommandExecute()
  {
      return this.CanRemove;
  }
  private bool RemoveCommandExecute()
  {
      if(!this.CanRemoveCommandExecute)
        return;
     //execution logic here
  }

据我所见,在您的MVVM中有一个bool"CanRemove"。您可以使用.NET 提供的BooleanToVisibilityConverter将其绑定到按钮可见性