我正在构建一个UserControl,它应该显示一个带有图像和文本的按钮。我像这样访问应用程序中的UserControl:
<local:ButtonWithImage
ButtonClick="Button1_Click"
ButtonImage="Assets/Clipboard 4.png"
ButtonText="Clipboard History"
ButtonWidth="200" />
在上面代码中显示的4个属性中,其中两个工作正常,它们是ButtonText和ButtonWidth。但是ButtonClick和ButtonImage属性会导致错误,我将在后面解释。
UserControl代码如下:
xaml:
<UserControl
x:Class="Launcher_WinUI3_Net_6.ButtonWithImage"
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:local="using:Launcher_WinUI3_Net_6"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="button">
<StackPanel Orientation="Horizontal">
<Image x:Name="image"/>
<TextBlock x:Name="textBlock" />
</StackPanel>
</Button>
</StackPanel>
<TextBlock Height="1" />
</StackPanel>
</UserControl>
c#:
public sealed partial class ButtonWithImage : UserControl
{
public ButtonWithImage()
{
this.InitializeComponent();
}
public string ButtonText
{
get { return (string)GetValue(ButtonTextProperty); }
set { SetValue(ButtonTextProperty, value); }
}
public static readonly DependencyProperty
ButtonTextProperty =
DependencyProperty.Register("ButtonText",
typeof(string), typeof(ButtonWithImage),
new PropertyMetadata(string.Empty, ButtonTextValue));
private static void ButtonTextValue(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var buttonWithImage = d as ButtonWithImage;
var buttonWithImageProperty = buttonWithImage.FindName("textBlock") as TextBlock;
buttonWithImageProperty.Text = e.NewValue.ToString();
}
public string ButtonWidth
{
get { return (string)GetValue(ButtonWidthProperty); }
set { SetValue(ButtonWidthProperty, value); }
}
public static readonly DependencyProperty
ButtonWidthProperty =
DependencyProperty.Register("ButtonWidth",
typeof(string), typeof(ButtonWithImage),
new PropertyMetadata(string.Empty, ButtonWidthValue));
private static void ButtonWidthValue(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var buttonWithImage = d as ButtonWithImage;
var buttonWithImageProperty = buttonWithImage.FindName("button") as Button;
buttonWithImageProperty.Width = Convert.ToDouble(e.NewValue.ToString());
}
public string ButtonClick
{
get { return (string)GetValue(ButtonClickProperty); }
set { SetValue(ButtonClickProperty, value); }
}
public static readonly DependencyProperty
ButtonClickProperty =
DependencyProperty.Register("ButtonClick",
typeof(string), typeof(ButtonWithImage),
new PropertyMetadata(string.Empty, ButtonClickValue));
private static void ButtonClickValue(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var buttonWithImage = d as ButtonWithImage;
var buttonWithImageProperty = buttonWithImage.FindName("button") as Button;
buttonWithImageProperty.Click += e.NewValue.ToString();
}
public string ButtonImage
{
get { return (string)GetValue(ButtonImageProperty); }
set { SetValue(ButtonImageProperty, value); }
}
public static readonly DependencyProperty
ButtonImageProperty =
DependencyProperty.Register("ButtonImage",
typeof(string), typeof(ButtonWithImage),
new PropertyMetadata(string.Empty, ButtonImageValue));
private static void ButtonImageValue(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var buttonWithImage = d as ButtonWithImage;
var buttonWithImageProperty = buttonWithImage.FindName("image") as Image;
buttonWithImageProperty.Source = e.NewValue.ToString();
}
}
ButtonClick的代码不能隐式地将类型'string'转换为'Microsoft.UI.Xaml.RoutedEventHandler'和ButtonImage的代码不能隐式地将类型'string'转换为'Microsoft.UI.Xaml.Media.ImageSource'
我在创建UserControls方面没有太多的经验,所以我遵循了一些我在互联网上看到的例子,但是它们都没有解决我面临的这两个问题。
========================================================
基于Andrew KeepCoding的回答更新1:
安德鲁谢谢! !没有重载'Button52_Click'匹配委托'EventHandler'
App中的UserControl:
<local:ButtonWithImage
ButtonImage="Assets/Clipboard 4.png"
ButtonText="Clipboard History"
ButtonWidth="200"
Click="Button52_Click" />
Button52_Click签名:
private void Button52_Click(object sender, RoutedEventArgs e)
{
foo();
}
UserControl 'Click'事件签名:
public event EventHandler? Click;
private void button_Click(object sender, RoutedEventArgs e)
{
Click?.Invoke(this, EventArgs.Empty);
}
签名是相同的,即使如此错误No overload for 'Button52_Click' matches delegate 'EventHandler'正在发生错误发生在这里,在'case 41:':
case 40: // MainWindow.xaml line 1288
{
global::Microsoft.UI.Xaml.Controls.Button element40 = global::WinRT.CastExtensions.As<global::Microsoft.UI.Xaml.Controls.Button>(target);
((global::Microsoft.UI.Xaml.Controls.Button)element40).Click += this.Button51_Click;
}
break;
case 41: // MainWindow.xaml line 1199
{
global::Launcher_WinUI3_Net_6.ButtonWithImage element41 = global::WinRT.CastExtensions.As<global::Launcher_WinUI3_Net_6.ButtonWithImage>(target);
((global::Launcher_WinUI3_Net_6.ButtonWithImage)element41).Click += this.Button52_Click;
}
break;
========================================================
更新2:Button52_Click签名应该是:
private void Button52_Click(object sender, EventArgs e)
{
foo();
}
而不是:
private void Button52_Click(object sender, RoutedEventArgs e)
{
foo();
}
您应该使用实际类型来代替typeof(string)
。
例如,我在下面的代码中使用ImageSource
作为ButtonImage
:
<UserControl
x:Class="UserControls.ButtonWithImage"
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"
mc:Ignorable="d">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button
x:Name="button"
Click="button_Click">
<StackPanel Orientation="Horizontal">
<Image
x:Name="image"
Source="{x:Bind ButtonImage, Mode=OneWay}" />
<TextBlock
x:Name="textBlock"
Text="{x:Bind ButtonText, Mode=OneWay}" />
</StackPanel>
</Button>
</StackPanel>
<TextBlock Height="1" />
</StackPanel>
</UserControl>
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using System;
namespace UserControls;
public sealed partial class ButtonWithImage : UserControl
{
public static readonly DependencyProperty ButtonTextProperty = DependencyProperty.Register(
nameof(ButtonText),
typeof(string),
typeof(ButtonWithImage),
new PropertyMetadata(default));
public static readonly DependencyProperty ButtonImageProperty = DependencyProperty.Register(
nameof(ButtonImage),
typeof(ImageSource),
typeof(ButtonWithImage),
new PropertyMetadata(default));
public ButtonWithImage()
{
this.InitializeComponent();
}
public event EventHandler? Click;
public string ButtonText
{
get => (string)GetValue(ButtonTextProperty);
set => SetValue(ButtonTextProperty, value);
}
public ImageSource? ButtonImage
{
get => (ImageSource?)GetValue(ButtonImageProperty);
set => SetValue(ButtonImageProperty, value);
}
private void button_Click(object sender, RoutedEventArgs e)
{
Click?.Invoke(this, EventArgs.Empty);
}
}
并像这样使用:
<local:ButtonWithImage
ButtonText="Text"
ButtonImage="Assets/StoreLogo.png"
Click="ButtonWithImage_Click" />
private void ButtonWithImage_Click(object sender, EventArgs e)
{
}
您还应该考虑从Button派生的自定义控件。这些视频可能会有帮助。
- 用户控件
- CustomControls