我有一個帶有以下代碼的 MVVM WPF 專案:
MultiplexerVM.cs
public class MultiplexerVM : BaseViewModel
{
public ObservableCollection<MultiplexVM> Multiplexes { get; set; } = new();
public MultiplexVM SelectedMultiplex { get; set; }
public ICommand CheckAll => new CheckBoxCommand(Multiplexes);
}
MultiplexVM.cs
public class MultiplexVM : BaseViewModel
{
public bool IsChecked { get; set; }
}
多路復用器V.xaml
<UserControl x:Class="MKVStudio.Views.MultiplexerV"
xmlns:vm="clr-namespace:MKVStudio.ViewModels"
xmlns:s="clr-namespace:System;assembly=mscorlib">
<UserControl.Resources>
<s:Boolean x:Key="True">True</s:Boolean>
<s:Boolean x:Key="False">False</s:Boolean>
</UserControl.Resources>
<Grid>
<ListView ItemsSource="{Binding Multiplexes}"
SelectedItem="{Binding SelectedMultiplex}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}"Margin="3"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
...
</GridView>
</ListView.View>
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding CheckAll}"
CommandParameter="{StaticResource True}">
<MenuItem.Header>
<TextBlock Text="Check all"/>
</MenuItem.Header>
</MenuItem>
<MenuItem Command="{Binding CheckAll}"
CommandParameter="{StaticResource False}">
<MenuItem.Header>
<TextBlock Text="Uncheck all"/>
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</ListView.ContextMenu>
</ListView>
</Grid>
</UserControl>
我的目標是結合IsEnabled背景關系選單項的財產IsChecked的MultiplexVM.cs。這個想法是實作一個IValueConverter(passing Multiplexesasvalue和 bool as parameter)。轉換器回傳value.Where(m => m.IsChecked == parameter).Count > 0。本質上,當所有Multiplexes都取消選中時,選單項Check all被啟用而選單項Uncheck all被禁用。當所有Multiplexes都被檢查時,相反的事情正在發生。這里的問題是轉換器在基本宣告時只被呼叫一次,檢查和取消選中專案不會觸發轉換器查看發生了什么。
我試圖實作一個IMultiValueConverter(但未能正確使用它)并傳遞三個這樣的值:
<MenuItem.IsEnabled>
<MultiBinding>
<Binding Source="{Binding Multiplexes.Count}" />
<Binding Source="{Binding Multiplexes}" />
<Binding Source="{StaticResource True}" /> <!--respectivly False to the other menu item-->
</MultiBinding>
</MenuItem.IsEnabled>
這不起作用。我試過<Binding Path="Multiplexes.Count" />和<Binding Path="Multiplexes" />,但也不起作用(傳遞給轉換器的值為Unset)。
我MultiBinding使用它的想法是否可行,使用它時我做錯了什么?
uj5u.com熱心網友回復:
為什么需要同時將 IsChecked 系結到 IsChecked 和 IsEnabled?如果從單一職責原則來看,這很奇怪。如果你確定你做對了,你可以這樣做:
<CheckBox IsChecked="{Binding IsChecked}"
IsEnabled="{Binding IsEnabled}" />
讓你的班級看起來像這樣:
public class MultiplexVM : BaseViewModel
{
public bool IsChecked
{
get => isChecked;
set
{
isChecked = value;
isEnabled = value;
RaisePropertyChanged(nameof(IsChecked));
RaisePropertyChanged(nameof(IsEnabled));
};
}
private bool isChecked;
public bool IsEnabled
{
get => isEnabled;
set
{
isChecked = value;
isEnabled = value;
RaisePropertyChanged(nameof(IsChecked));
RaisePropertyChanged(nameof(IsEnabled));
};
}
private bool isChecked;
}
uj5u.com熱心網友回復:
據我了解,您想讓系結到“父”的物件(MenuItem => MultiplexerVM)依賴于其子集合的屬性(CheckBox => MultiplexVM.IsChecked,它是 中的一個專案MultiplexerVM.Multiplexes)
在這種情況下,子級必須以某種方式知道其父級(當子級更改時,它必須將更改“推送”給父級;換句話說,必須在發生更改時通知父級)。
我可以想到兩種方法來做到這一點:
在 VM 級別:在 every 中
MultiplexVM,設定對父視圖模型或集合的參考,然后您可以在CanCheckAll / CanUncheckAll每次孩子IsChecked更改時更新功能(無論您如何實作它)(乏味;我想您也可以使用事件來執行此操作,但是將PropertyChanged處理程式附加到每個子項也有點多)通過使用 GUI 級別作弊:您可以
CanCheckAll / CanUncheckAll在CheckBox單擊時更新功能
下面是如何實作第二個版本的示例。
在您的MultiplexerVM:
public bool CanCheckAll => Multiplexes.Any(a => !a.IsChecked);
public bool CanUncheckAll => Multiplexes.Any(a => a.IsChecked);
public void RefreshCheckUncheckAll()
{
NotifyPropertyChanged(nameof(CanCheckAll));
NotifyPropertyChanged(nameof(CanUncheckAll));
}
然后,呼叫RefreshCheckUncheckAll()的CheckAll命令執行情況和:
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
((MultiplexerVM)this.DataContext).RefreshCheckUncheckAll();
}
然后,xaml 將如下所示:
<ListView ItemsSource="{Binding Multiplexes}" SelectedItem="{Binding SelectedMultiplex}">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem
Command="{Binding CheckAll}"
CommandParameter="{StaticResource True}"
IsEnabled="{Binding CanCheck}">
<MenuItem.Header>
<TextBlock Text="Check all" />
</MenuItem.Header>
</MenuItem>
<MenuItem
Command="{Binding CheckAll}"
CommandParameter="{StaticResource False}"
IsEnabled="{Binding CanUncheck}">
<MenuItem.Header>
<TextBlock Text="Uncheck all" />
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</ListView.ContextMenu>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Margin="3" Text="{Binding Name}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="3" IsChecked="{Binding IsChecked}" Click="CheckBox_Click" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/388297.html
