gpt4 book ai didi

c# - 如何将绑定(bind)重定向到 XAML 控件的 "outside"

转载 作者:太空宇宙 更新时间:2023-11-03 12:44:23 27 4
gpt4 key购买 nike

假设我有一个带有 ContextMenuListView。我想将它用作名为 ListViewWithContextMenu 的单独控件。如何从 ContextMenu 重定向命令绑定(bind),以便它们在 ListViewWithContextMenu 中可见?

示例代码:

ListViewWithContextMenu.xaml

<ListView x:Class="WpfApplication4.ListViewWithContextMenu"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication4"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:ListViewWithContextMenu}}, Path= PreviewCommand}" />
</ContextMenu>
</ListView.ContextMenu>

ListViewWithContextMenu.xaml.cs

using System.Windows;
using System.Windows.Input;

namespace WpfApplication4
{
public partial class ListViewWithContextMenu
{
public ICommand PreviewCommand
{
get { return (ICommand)GetValue(PreviewCommandProperty); }
set { SetValue(PreviewCommandProperty, value); }
}

public static readonly DependencyProperty PreviewCommandProperty =
DependencyProperty.Register("PreviewCommand", typeof(ICommand), typeof(ListViewWithContextMenu));

public ListViewWithContextMenu()
{
InitializeComponent();
}
}
}

MainWindow.xaml

<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication4"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext><local:MainWidnowViewModel></local:MainWidnowViewModel></Window.DataContext>
<Grid>
<local:ListViewWithContextMenu PreviewCommand="{Binding Preview}"></local:ListViewWithContextMenu>
</Grid>
</Window>

MainWindowViewModel.cs

using System.Windows;
using System.Windows.Input;
using Microsoft.Practices.Prism.Commands;

namespace WpfApplication4
{
public class MainWidnowViewModel
{
public MainWidnowViewModel()
{
Preview = new DelegateCommand(PreviewMethod);
}

private void PreviewMethod()
{
MessageBox.Show("PREVIEW");
}

public ICommand Preview { get; set; }
}
}

此代码没有调用我想要实现的 ViewModel 中的 PreviewMethod

最佳答案

首先,不要将“ListViewWithDataContext”创建为常规用户控件,而是将其创建为 WPF“CustomControl”。为此,请执行以下步骤:

  • 删除现有的“ListViewWithDataContext”控件
  • 右键单击您的项目,然后单击“添加新项”->“自定义控件 (WPF)”。 Custom Control

  • Visual Studio 会自动创建一个新的项目文件夹“Themes”,并在其下创建一个名为“Generic.xaml”的新 .xaml 文件,如下所示:

enter image description here

  • Visual Studio 还将创建一个名为“ListViewWithContextMenu.cs”的直接 C# 类文件

从此处复制以下代码并将其粘贴到相应的文件中:

通用.xaml

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4">


<Style TargetType="{x:Type local:ListViewWithContextMenu}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ListViewWithContextMenu}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">

<Border.ContextMenu>
<ContextMenu>
<MenuItem Command="{TemplateBinding PreviewCommand}" />
</ContextMenu>
</Border.ContextMenu>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

ListViewWithContextMenu:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication4
{

public class ListViewWithContextMenu : ListView
{

public ICommand PreviewCommand
{
get { return (ICommand)GetValue(PreviewCommandProperty); }
set { SetValue(PreviewCommandProperty, value); }
}

public static readonly DependencyProperty PreviewCommandProperty =
DependencyProperty.Register("PreviewCommand", typeof(ICommand), typeof(ListViewWithContextMenu));


static ListViewWithContextMenu()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ListViewWithContextMenu), new FrameworkPropertyMetadata(typeof(ListViewWithContextMenu)));
}
}
}

我测试了它,它有效。

It works

我们在这里做了什么:由于我们想要做的只是利用现有的 ListView 控件,而不是更改任何现有的 UI 外观,我们只是创建了一个实质上覆盖当前模板的 ListView“CustomControl”。在 .cs 文件中,我们定义了 PreviewCommand DependencyProperty。

在 Generic.xaml 文件中,我们使用“Border”作为根级控件来放置控件(尽管我们可以使用 Grid 或诸如此类的东西),并向其添加了上下文菜单。

关于c# - 如何将绑定(bind)重定向到 XAML 控件的 "outside",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37856330/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com