C# 在WPF中,使用按钮和弹出窗口构建用户控件,以及如何在单击菜单项时隐藏弹出窗口?
我正在构建一个名为C# 在WPF中,使用按钮和弹出窗口构建用户控件,以及如何在单击菜单项时隐藏弹出窗口?,c#,wpf,mvvm,user-controls,popup,C#,Wpf,Mvvm,User Controls,Popup,我正在构建一个名为MenuPopup的用户控件。我在MVVM项目中使用这个控件 它是这样的: 但是现在,我没有理想的方法在单击一个菜单项后隐藏弹出窗口。如果通过菜单项的单击事件隐藏它,那么如何将命令绑定到ViewModel以处理业务逻辑 <!--MenuPopup.xaml--> <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="ht
MenuPopup
的用户控件。我在MVVM项目中使用这个控件
它是这样的:
但是现在,我没有理想的方法在单击一个菜单项后隐藏弹出窗口。如果通过菜单项的单击事件隐藏它,那么如何将命令绑定到ViewModel以处理业务逻辑
<!--MenuPopup.xaml-->
<UserControl
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:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
mc:Ignorable="d"
x:Class="WpfApplication10.MenuPopup"
x:Name="UserControl">
<UserControl.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
<Geometry x:Key="ArrowGraph">M 3,6 L 13,6 L 8,12 Z</Geometry>
<Geometry x:Key="LineGraph" >M 12.3,7 L 9,11</Geometry>
<Style x:Key="ArrowMenuButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="#00FFFFFF"/>
<Setter Property="BorderBrush" Value="#FFFFFFFF"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" BorderThickness="1"/>
<Path x:Name="ArrowPath" Data="{StaticResource ArrowGraph}" Fill="#FFFFFFFF"/>
<Path x:Name="LinePath" Data="{StaticResource LineGraph}" Fill="#FFD5D5D5" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="ToggleButton.IsChecked" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#FF219266"/>
<Setter Property="BorderBrush" Value="#FF167559"/>
<Setter Property="Fill" TargetName="LinePath" Value="#FF1E7B57"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" Value="#FF219266"/>
<Setter Property="BorderBrush" Value="#FF7ABEA3"/>
<Setter Property="Fill" TargetName="LinePath" Value="#FF1E7B57"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<Grid>
<Button x:Name="MenuButton" Click="MenuButton_Click" Content="" Width="16" Height="16" BorderThickness="0" Padding="0" Style="{DynamicResource ArrowMenuButtonStyle}" />
<Popup x:Name="MenuButtonPopup" StaysOpen="False" PlacementTarget="{Binding ElementName=MenuButton}" >
<Grid>
<Border Background="White">
<StackPanel >
<MenuItem Header="XX1" />
<MenuItem Header="XX2" />
</StackPanel>
</Border>
</Grid>
</Popup>
</Grid>
</Grid>
</UserControl>
您可以将viewmodel上的bool属性设置为IsPopupOpen,并将Popup.IsOpen绑定到此属性。现在,将按钮命令绑定到ViewModel中定义的命令,并将commandhandler中的IsPopupOpen设置为false
谢谢如果您是这样要求的,您可以使用
命令绑定
将事件路由到视图模型。哦,我应该尝试使用click事件处理程序和commandbinding。我同时使用click事件和命令,效果很好。我只是认为隐藏弹出窗口可以在视图层中处理。如果我的观点是错误的,请告诉我,我只是一个新手。你在使用MVVM吗,即你是否有ViewModel支持你的视图(userControl)?在MVVM中,我使用userControl中的Commond绑定按钮到MainViewModel(因为主界面中使用了userControl)并处理一些业务逻辑。我是否应该创建一个专用的ViewModel以用于UserControl?这就是我要说的,您可以在MainViewModel中拥有另一个属性,并将其绑定到IsPopupOpen,并在button命令的命令处理程序中将IsPopupOpen设置为false。将绑定模式设置为双向
// MenuPopup.xaml.cs
namespace WpfApplication10
{
/// <summary>
/// Interaction logic for MenuPopup.xaml
/// </summary>
public partial class MenuPopup : UserControl
{
public MenuPopup()
{
this.InitializeComponent();
}
private void MenuButton_Click(object sender, RoutedEventArgs e)
{
MenuButtonPopup.IsOpen = true;
}
}
}
<!--parts in MenuPopup.xaml -->
<Grid x:Name="LayoutRoot">
<Button x:Name="MenuButton" Click="MenuButton_Click" Content="" Width="16" Height="16" BorderThickness="0" Padding="0" Style="{DynamicResource ArrowMenuButtonStyle}" />
<Popup x:Name="MenuButtonPopup" StaysOpen="False" PlacementTarget="{Binding ElementName=MenuButton}" >
<Grid>
<Border Background="White">
<StackPanel >
<MenuItem Header="XX1" Click="MenuItem_Click" Command="{Binding IncreaseCommand}"/>
<MenuItem Header="XX2" Click="MenuItem_Click" />
</StackPanel>
</Border>
</Grid>
</Popup>
</Grid>
// MenuPopup.xaml.cs
namespace WpfApplication10
{
/// <summary>
/// Interaction logic for MenuPopup.xaml
/// </summary>
public partial class MenuPopup : UserControl
{
public MenuPopup()
{
this.InitializeComponent();
}
private void MenuButton_Click(object sender, RoutedEventArgs e)
{
MenuButtonPopup.IsOpen = true;
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
MenuButtonPopup.IsOpen = false;
}
}
}
// MainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
namespace WpfApplication10.ViewModel
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
IncreaseCommand = new RelayCommand(() => ++Cnt);
}
private int cnt = 0;
public int Cnt
{
get { return cnt; }
set { cnt = value; RaisePropertyChanged("Cnt"); }
}
private RelayCommand increaseCommand;
public RelayCommand IncreaseCommand { get; private set; }
}
}