WPF 菜单项行为?
WPF Menu item behaviour?
我试图在万维网上四处寻找,但没有成功,我的应用程序中有一个用于打开文件夹的按钮 select 对话框,它是以这种方式实现的:
<Button Grid.Column="0" Margin="5" Content="Select Folder" Style="{StaticResource MaterialDesignRaisedLightButton}">
<i:Interaction.Behaviors>
<FolderDialog:FolderDialogBehavior SetterName="FolderName"></FolderDialog:FolderDialogBehavior>
</i:Interaction.Behaviors>
</Button>
现在我需要在菜单项中使用这种行为(当然还有另一个 SetterName),但是我无法找到解决方案来完成我的任务,有人可以帮我吗?
<Menu Background="#292A24" Foreground="Yellow" VerticalAlignment="Top" IsMainMenu="True">
<MenuItem Header="_File" Height="35">
<MenuItem Header="Export to csv">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="Export" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Exit" InputGestureText="Ctrl+E">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="ExitToApp" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
菜单项有 its own Click event。所以你必须为 MenuItem
创建新的行为 class
public class FolderDialogBehavior : Behavior<MenuItem>
{
public string SetterName { get; set; }
protected override void OnAttached()
{
AssociatedObject.Click += OnClick;
}
protected override void OnDetaching()
{
AssociatedObject.Click -= OnClick;
}
private void OnClick(object sender, RoutedEventArgs e)
{
var dialog = new FolderBrowserDialog();
var result = dialog.ShowDialog();
if (result == DialogResult.OK && AssociatedObject.DataContext != null)
{
var propertyInfo = AssociatedObject.DataContext.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanRead && p.CanWrite)
.Where(p => p.Name.Equals(SetterName))
.First();
propertyInfo.SetValue(AssociatedObject.DataContext, dialog.SelectedPath, null);
}
}
}
如果你想要单一行为class你可以通过反射定义订阅
private RoutedEvent _clickEvent;
protected override void OnAttached()
{
var memberInfo = AssociatedObject.GetType().GetProperty("ClickEvent");
if (memberInfo == null)
{
return;
}
_clickEvent = memberInfo.GetValue(AssociatedObject) as RoutedEvent
if (_clickEvent == null)
{
return;
}
AssociatedObject.AddHandler(_clickEvent, OnClick);
}
protected override void OnDetaching()
{
if (_clickEvent == null)
{
return;
}
AssociatedObject.RemoveHandler(_clickEvent, OnClick);
}
我试图在万维网上四处寻找,但没有成功,我的应用程序中有一个用于打开文件夹的按钮 select 对话框,它是以这种方式实现的:
<Button Grid.Column="0" Margin="5" Content="Select Folder" Style="{StaticResource MaterialDesignRaisedLightButton}">
<i:Interaction.Behaviors>
<FolderDialog:FolderDialogBehavior SetterName="FolderName"></FolderDialog:FolderDialogBehavior>
</i:Interaction.Behaviors>
</Button>
现在我需要在菜单项中使用这种行为(当然还有另一个 SetterName),但是我无法找到解决方案来完成我的任务,有人可以帮我吗?
<Menu Background="#292A24" Foreground="Yellow" VerticalAlignment="Top" IsMainMenu="True">
<MenuItem Header="_File" Height="35">
<MenuItem Header="Export to csv">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="Export" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Exit" InputGestureText="Ctrl+E">
<MenuItem.Icon>
<materialDesign:PackIcon Kind="ExitToApp" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
菜单项有 its own Click event。所以你必须为 MenuItem
创建新的行为 classpublic class FolderDialogBehavior : Behavior<MenuItem>
{
public string SetterName { get; set; }
protected override void OnAttached()
{
AssociatedObject.Click += OnClick;
}
protected override void OnDetaching()
{
AssociatedObject.Click -= OnClick;
}
private void OnClick(object sender, RoutedEventArgs e)
{
var dialog = new FolderBrowserDialog();
var result = dialog.ShowDialog();
if (result == DialogResult.OK && AssociatedObject.DataContext != null)
{
var propertyInfo = AssociatedObject.DataContext.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanRead && p.CanWrite)
.Where(p => p.Name.Equals(SetterName))
.First();
propertyInfo.SetValue(AssociatedObject.DataContext, dialog.SelectedPath, null);
}
}
}
如果你想要单一行为class你可以通过反射定义订阅
private RoutedEvent _clickEvent;
protected override void OnAttached()
{
var memberInfo = AssociatedObject.GetType().GetProperty("ClickEvent");
if (memberInfo == null)
{
return;
}
_clickEvent = memberInfo.GetValue(AssociatedObject) as RoutedEvent
if (_clickEvent == null)
{
return;
}
AssociatedObject.AddHandler(_clickEvent, OnClick);
}
protected override void OnDetaching()
{
if (_clickEvent == null)
{
return;
}
AssociatedObject.RemoveHandler(_clickEvent, OnClick);
}