gpt4 book ai didi

wpf - 自定义 WPF 控件可以实现 IsDefault 属性吗

转载 作者:行者123 更新时间:2023-12-04 17:03:51 25 4
gpt4 key购买 nike

我有一个不是从 Button 派生的自定义按钮控件。我是否可以实现等效于 IsDefault 以便将调用与我的控件关联的命令。我希望这是一个附加属性,我可以添加到任何控件中,但据我所知它似乎不是。如果我的控件不是从 Button 派生的,或者至少有一个合理的解决方法,我会走运​​吗?

更新:
我只是用反射器看了一眼 Button 在下面是如何完成的,我必须说这不是我见过的最不言自明的代码。似乎至少有 3 个依赖属性和一些自定义类型只是为了处理 Button 是默认的概念。由于似乎没有现有的方式来借用 IsDefault 功能,我想我必须缩小我想要实现的范围,以便我至少可以获得默认焦点和访问键处理工作而忽略Button.IsDefault 实现中涉及的复杂性。

更新:
添加了以下代码示例,显示我在尝试 itowlson 的建议时的失败尝试。

我的按钮.xaml

<UserControl x:Class="IsDefault.MyButton"
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"
mc:Ignorable="d"
Height="28"
Width="117">

<Grid>
<Button Click="Button_Click">
<Button.Template>
<ControlTemplate>
<Border BorderThickness="2"
CornerRadius="12"
Background="DarkSlateBlue">
<TextBlock Foreground="WhiteSmoke"
HorizontalAlignment="Center"
VerticalAlignment="Center">Some Text</TextBlock>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</UserControl>

我的按钮.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 IsDefault
{
/// <summary>
/// Interaction logic for MyButton.xaml
/// </summary>
public partial class MyButton : UserControl
{


// Provide CLR accessors for the event
public event RoutedEventHandler Click
{
add { AddHandler(ClickEvent, value); }
remove { RemoveHandler(ClickEvent, value); }
}

// Using a RoutedEvent
public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent(
"Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButton));



public bool IsDefault
{
get { return (bool)GetValue(IsDefaultProperty); }
set { SetValue(IsDefaultProperty, value); }
}

public static readonly DependencyProperty IsDefaultProperty =
DependencyProperty.Register(
"IsDefault",
typeof(bool),
typeof(MyButton),
new PropertyMetadata(false, IsDefault_PropertyChangedCallback, null));


public MyButton()
{
InitializeComponent();
}

protected override void OnAccessKey(AccessKeyEventArgs e)
{
base.OnAccessKey(e);

if (e.Key == "\r")
{
if (e.IsMultiple)
{
// There are multiple controls that are currently handling the Enter key
MessageBox.Show("there are multiple controls handling the Enter key.");
}
else
{
RaiseEvent(new RoutedEventArgs(ClickEvent, this));
}
}
}

private static void IsDefault_PropertyChangedCallback(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var button = d as MyButton;

var isDefault = (bool)e.NewValue;

if (isDefault)
{
AccessKeyManager.Register("\r", button);
}
else
{
AccessKeyManager.Unregister("\r", button);
}
}

private void Button_Click(object sender, RoutedEventArgs e)
{
RaiseEvent(new RoutedEventArgs(ClickEvent));
}
}
}

主窗口.xaml
<Window x:Class="IsDefault.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:my="clr-namespace:IsDefault">
<Grid>
<Button Content="Button"
Height="23"
HorizontalAlignment="Left"
Margin="224,24,0,0"
Name="button1"
VerticalAlignment="Top"
Width="75" />
<TextBox Height="23"
HorizontalAlignment="Left"
Margin="208,94,0,0"
Name="textBox1"
VerticalAlignment="Top"
Width="120" />
<my:MyButton Height="28"
HorizontalAlignment="Left"
Margin="232,154,0,0"
x:Name="myButton1"
VerticalAlignment="Top"
Width="117"
Click="myButton1_Click"
IsDefault="True"/>
</Grid>
</Window>

主窗口.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 IsDefault
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void myButton1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("My button was clicked, yay!");
}
}
}

最佳答案

所有设置 Button.IsDefault 所做的就是调用 AccessKeyManager.Register("\r", this) (如果设置为 false,则取消注册)。 (实际上,它围绕焦点管理做了一些额外的工作,但这对您来说可能并不重要。)

所以要自己实现类似的效果:

  • 以通常的方式创建 IsDefault 依赖项属性。
  • 在您的 IsDefault PropertyChangedCallback 中,调用 AccessKeyManager.RegisterAccessKeyManager.Unregister根据新值,通过 "\r" (输入字符串)作为键,控件实例作为元素。
  • 覆盖 OnAccessKey指定您的控件如何响应 Enter 键。 (例如,ButtonBase 覆盖它以调用 OnClick。您也可以处理 AccessKeyManager.AccessKeyPressed 附加事件,但由于您正在定义自定义控件,因此覆盖 OnAccessKey 更简洁。)
  • 关于wpf - 自定义 WPF 控件可以实现 IsDefault 属性吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2633886/

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