簡體   English   中英

WinUI 3 中的 UserControl:如何設置圖像的“來源”屬性和按鈕的“點擊”事件?

[英]UserControl in WinUI 3: how to set the 'source' property of an image and the 'click' event of a button?

我正在構建一個應該顯示帶有圖像和文本的按鈕的 UserControl。 我像這樣在應用程序中訪問該 UserControl:

<local:ButtonWithImage
ButtonClick="Button1_Click"
ButtonImage="Assets/Clipboard 4.png"
ButtonText="Clipboard History"
ButtonWidth="200" />

在上面代碼中顯示的 4 個屬性中,有兩個工作正常,它們是 ButtonText 和 ButtonWidth。 但是 ButtonClick 和 ButtonImage 屬性導致錯誤,我將在接下來解釋。

用戶控件代碼是這樣的:

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的代碼生成此錯誤:無法將類型“字符串”隱式轉換為“Microsoft.UI.Xaml.RoutedEventHandler”

ButtonImage的代碼生成此錯誤:無法將類型“字符串”隱式轉換為“Microsoft.UI.Xaml.Media.ImageSource”

我在創建用戶控件方面沒有太多經驗,所以我按照我在 inte.net 上看到的一些示例進行操作,但它們都沒有解決我面臨的這兩個問題。

================================================ ======

根據 Andrew KeepCoding 的回答更新 1:

謝謝安德魯:!! 仍然存在錯誤: “Button52_Click”沒有重載匹配委托“EventHandler”

應用程序中的用戶控件:

<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();
}

用戶控件“單擊”事件簽名:

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' 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;

================================================ ======

更新 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 的自定義控件。 這些視頻可能會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM