与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();
}
}
当您可以使用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将其绑定到按钮可见性