在我的ListBox中,我有需要绑定到ItemsSource和Viewmodel中的属性的控件。您可以看到按钮需要同时执行这两个操作。我似乎能够做到这一点的唯一方法是非常难看(参见IsEnabled属性绑定到视图的视图模型)。我想知道最好的办法是什么。
编辑:澄清我想将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>
视图模型
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();
}
}
答案 0 :(得分:1)
当你做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
}
答案 1 :(得分:1)
当您可以使用 RelativeSource
标记扩展程序直接访问ViewModel时,您根本不需要转换器。这应该有效:
<Button IsEnabled="{Binding DataContext.CanRemove,
RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}"/>
由于ListBox的DataContext指向viewModel实例,因此上面发布的代码将起作用。
答案 2 :(得分:0)
据我所知,你的MVVM中有一个bool&#34; CanRemove&#34;。您可以使用.NET提供的BooleanToVisibilityConverter将其绑定到按钮可见性