[英]UserControl in WinUI 3: how to set the 'source' property of an image and the 'click' event of a button?
I'm building a UserControl that should display a button with an image and text.我正在构建一个应该显示带有图像和文本的按钮的 UserControl。 I access that UserControl in the App like this:我像这样在应用程序中访问该 UserControl:
<local:ButtonWithImage
ButtonClick="Button1_Click"
ButtonImage="Assets/Clipboard 4.png"
ButtonText="Clipboard History"
ButtonWidth="200" />
Out of the 4 properties displayed in the code above, two of them are working fine, which are ButtonText and ButtonWidth.在上面代码中显示的 4 个属性中,有两个工作正常,它们是 ButtonText 和 ButtonWidth。 But the ButtonClick and ButtonImage properties are causing errors, which I'll explain next.但是 ButtonClick 和 ButtonImage 属性导致错误,我将在接下来解释。
The UserControl code is this:用户控件代码是这样的:
xaml: 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#: 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();
}
}
The code for the ButtonClick is generating this error: Cannot implicitly convert type 'string' to 'Microsoft.UI.Xaml.RoutedEventHandler' ButtonClick的代码生成此错误:无法将类型“字符串”隐式转换为“Microsoft.UI.Xaml.RoutedEventHandler”
And the code for the ButtonImage is generating this error: Cannot implicitly convert type 'string' to 'Microsoft.UI.Xaml.Media.ImageSource' ButtonImage的代码生成此错误:无法将类型“字符串”隐式转换为“Microsoft.UI.Xaml.Media.ImageSource”
I don't have much experience with creating UserControls so I'm following some examples I've seen on the inte.net, but none of them address these two problems I'm facing.我在创建用户控件方面没有太多经验,所以我按照我在 inte.net 上看到的一些示例进行操作,但它们都没有解决我面临的这两个问题。
======================================================== ================================================ ======
Update 1 based on answer from Andrew KeepCoding:根据 Andrew KeepCoding 的回答更新 1:
Thanks Andrew:!!谢谢安德鲁:!! There is still an error going on: No overload for 'Button52_Click' matches delegate 'EventHandler'仍然存在错误: “Button52_Click”没有重载匹配委托“EventHandler”
UserControl in the App:应用程序中的用户控件:
<local:ButtonWithImage
ButtonImage="Assets/Clipboard 4.png"
ButtonText="Clipboard History"
ButtonWidth="200"
Click="Button52_Click" />
Button52_Click signature: Button52_Click 签名:
private void Button52_Click(object sender, RoutedEventArgs e)
{
foo();
}
UserControl 'Click' event signature:用户控件“单击”事件签名:
public event EventHandler? Click;
private void button_Click(object sender, RoutedEventArgs e)
{
Click?.Invoke(this, EventArgs.Empty);
}
The signatures are the same, even so the error No overload for 'Button52_Click' matches delegate 'EventHandler' is occurring The error is occurring here, in 'case 41:':签名是相同的,即便如此错误No overload for 'Button52_Click' matches delegate 'EventHandler' is occurring The error is occurring here, in '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;
======================================================== ================================================ ======
Update 2: The Button52_Click signature should be:更新 2:Button52_Click 签名应该是:
private void Button52_Click(object sender, EventArgs e)
{
foo();
}
And not:并不是:
private void Button52_Click(object sender, RoutedEventArgs e)
{
foo();
}
Instead of typeof(string)
, you should use the actual type for your dependency properties.您应该为依赖属性使用实际类型,而不是typeof(string)
。
For example, I'm using ImageSource
for the ButtonImage
in the code below:例如,我在下面的代码中使用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);
}
}
And use it like this:并像这样使用它:
<local:ButtonWithImage
ButtonText="Text"
ButtonImage="Assets/StoreLogo.png"
Click="ButtonWithImage_Click" />
private void ButtonWithImage_Click(object sender, EventArgs e)
{
}
You should also consider a custom control derived from a Button.您还应该考虑派生自 Button 的自定义控件。 These videos might help.这些视频可能会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.