有一個 WPF MVVM 應用程式。在主視圖上,我有一個元素串列,這些元素用 定義ListView.ItemTemplate,因為我想要一個帶有洗掉操作的背景關系選單。
Command與視圖分離的for 并保存在 ViewModel DreamListingViewModel中。
問題是,在單擊 Delete 時,我無法讓它在 ViewModelk 上執行命令,因為背景關系是專案的,而不是專案容器的。
我可以通過將背景關系選單定義移動到串列視圖元素之外以某種方式使其作業,但是當我打開背景關系選單時,它會閃爍,好像它被稱為“20”次(我認為確實發生了有時我在集合中有元素),無論如何,我需要一個干凈的解決方案,而且我對 XAML 非常不滿意。
這是我的視圖的外觀:
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="0 5 0 5" Background="Transparent" Width="auto">
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"
Command="{Binding DeleteSelectedDream}"
CommandParameter="{Binding DeleteSelectedDream,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type viewmodels:DreamListingViewModel}}}"
/>
</ContextMenu>
</Grid.ContextMenu>
...
它是主視窗,并在 App.cs 的通用主機中初始化:
public partial class App : Application
{
private readonly IHost _host;
public App()
{
...
_host = Host.CreateDefaultBuilder().ConfigureServices(services =>
{
...
services.AddTransient<DreamListingViewModel>();
services.AddSingleton((s) => new DreamListingView()
{
DataContext = s.GetRequiredService<DreamListingViewModel>()
});
...
}).Build();
Command 和 CommandParameter 值是我一直在試驗的,但它不起作用
這是我的 ViewModel 的外觀:
internal class DreamListingViewModel : ViewModelBase
{
public ICommand DeleteSelectedDream{ get; }
...
最后,當命令被觸發時,我需要傳遞顯示選單的當前元素。
所以,這就是我想要的:
- 用戶使用滑鼠右鍵單擊串列項 - 確定
- 看到一個帶有洗掉條目的選單 - 確定
- 在 Delete 單擊時,以當前夢想(串列中的專案)作為引數觸發命令 DeleteSelectedDream - ERR
uj5u.com熱心網友回復:
您的示例有些缺乏必要的資訊,但我會盡力提供幫助。
首先,您需要驗證您是否確實系結到您的視圖模型。您使用的是 Prism 還是標準的 WPF?在視圖代碼隱藏的建構式中,將DataContext設定為 VM 的實體。
InitializeComponent();
this.DataContext = new DreamListingViewModel();
現在,您通過模式“FindAncestor”系結到相對源,并且 AncestorType 設定為視圖模型的型別。這通常不起作用,因為視圖模型自然不是WPF 視圖的可視化樹的一部分。也許您的 ItemTemplate 以某種方式將其連接起來。在我的一個大型 WPF 應用程式中,我使用 Telerik UI for WPF 和類似的方法,但是,我將背景關系選單的DataContext設定為設定為Self的RelativeSource并結合設定為PlacementTarget.DataContext的路徑。
在我的示例中,您不必使用所有 XAML,只需觀察我是如何做到的。將 'RadContextMenu' 與 'ContextMenu' 交換,忽略挪威語 - 在這里只使用你需要的:
<telerik:RadContextMenu x:Key="CanceledOperationsViewContextMenu" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}, Path=PlacementTarget.DataContext, UpdateSourceTrigger=PropertyChanged}">
<MenuItem Header="{Binding PatientName}" IsEnabled="False" Style="{StaticResource ContextMenuHeading}" />
<MenuItem Header="G? til aktuell SomeAcme-liste" IsEnabled="{Binding IsValid}" Command="{Binding NavigateToListCommand}" />
<MenuItem Header="?pne protokoll..." Command="{Binding CommonFirstProtocolCommand, Mode=OneWay}" CommandParameter="{Binding}" />
<MenuItem Header="?pne Opr.spl.rapport...." Command="{Binding CommonFirstNurseReportCommand, Mode=OneWay}" CommandParameter="{Binding}" />
</telerik:RadContextMenu>
在您的示例中,它將是:
<ContextMenu x:Key="SomeContextMenu" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}, Path=PlacementTarget.DataContext, UpdateSourceTrigger=PropertyChanged}">
<MenuItem Header="Delete" />
Command="{Binding DeleteSelectedDream}"
CommandParameter="{Binding DeleteSelectedDream,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListViewItem}}}"
/>
</telerik:RadContextMenu>
現在我在這里認為您正在使用類ListViewItem https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.listviewitem?view=netframework-4.8 您可能需要指定 DataContext .DeleteSelectedDream 在這里確保您系結到您的 ICommand 實作所在的 DataContext。
uj5u.com熱心網友回復:
偶然發現了這個答案,這基本上就是我需要的,只是添加到它CommandParameter來發送專案,它就像魔術一樣作業!
<ListView Name="lvDreams" ItemsSource="{Binding Dreams}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="0 5 0 5" Background="Transparent" Width="auto">
<Grid.ContextMenu>
<ContextMenu>
<MenuItem
Header="Delete"
Command="{Binding DataContext.DeleteSelectedDream, Source={x:Reference lvDreams}}"
CommandParameter="{Binding}"
/>
</ContextMenu>
</Grid.ContextMenu>
...
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/460097.html
