出现异常:“值未落在预期范围内。”在WinUI3中设置AppBarButton的Icon属性时

问题描述 投票:0回答:1

我正在使用WinUI3设计一个界面。我想使用

AppBarButton
列表来通过
Icon
AppBarButton
显示连接状态。

因为状态会改变,所以我使用了两个

FontIcon
,分别命名为
disconnectedIcon
connectedIcon
,并将
Icon
属性设置为其中之一来显示当前连接状态。

点击

ContentDialog
connectDialog
后,会弹出一个名为
stest1ConnectionButton
stest2ConnectionButton
,让用户填写机器的名称(可选)和机器的IP地址。

单击

Connect
中的
connectDialog
按钮后,进程将开始连接。连接完成后,按钮的
Icon
将设置为
connectedIcon
。反之亦然。

但是,在运行设置

Icon
属性的代码时,有时会弹出此错误(不仅仅是弹出
connectDialog
的代码):

System.ArgumentException:“值不在预期范围内。”


以下是代码:

MainWindow.xaml

<Window
    x:Class="TesterWinUI3_240606.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TesterWinUI3_240606"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid RowDefinitions="auto,*,auto,auto,auto,*,auto,auto" ColumnDefinitions="auto, auto, auto, *">
        
        <!--Upper part-->
        <Grid Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3">
            <Border BorderBrush="{ThemeResource ControlStrongStrokeColorDefaultBrush}" BorderThickness="2.5" CornerRadius="3" Margin="5">
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
                     <!--Title at the top--> 
                    <TextBlock Text="Connection" FontSize="16" FontWeight="Bold" Margin="5"/>

                     <!--Connection settings-->
                    <AppBarElementContainer VerticalAlignment="Center">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Gyro" Margin="5"/>
                            <AppBarButton x:Name="gyroConnectionButton" Label="Disconnected" Width="80" Click="gyroConnectionButton_Click">
                                <FontIcon Glyph="&#xF78A;"/>
                            </AppBarButton>
                        </StackPanel>
                    </AppBarElementContainer>
                    <AppBarSeparator/>
                    <AppBarElementContainer VerticalAlignment="Center">
                        <StackPanel Orientation="Vertical">
                            <TextBlock x:Name="stest1NameTextBlock" Text="S-TEST 1" Margin="5"/>
                            <AppBarButton x:Name="stest1ConnectionButton" Label="Disconnected" Width="80" Click="stest1ConnectionButton_Click">
                                <FontIcon Glyph="&#xF78A;"/>
                                <!--<FontIcon Glyph="&#xEB90;"/>-->
                            </AppBarButton>
                        </StackPanel>
                    </AppBarElementContainer>
                    <AppBarElementContainer VerticalAlignment="Center">
                        <StackPanel Orientation="Vertical">
                            <TextBlock x:Name="stest2NameTextBlock" Text="S-TEST 2" Margin="5"/>
                            <AppBarButton x:Name="stest2ConnectionButton" Label="Disconnected" Width="80" Click="stest2ConnectionButton_Click">
                                <FontIcon Glyph="&#xF78A;"/>
                            </AppBarButton>
                        </StackPanel>
                    </AppBarElementContainer>
                </StackPanel>
            </Border>
        </Grid>
        
        <!-- Other UI -->
        
    </Grid>
</Window>

MainWindow.xaml.cs

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System.Drawing.Text;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.ApplicationModel.DataTransfer;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace TesterWinUI3_240606
{
    /// <summary>
    /// An empty window that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainWindow : Window
    {
        // ...

        // Flags for connection status
        private bool isGyroConnected = false;
        private bool isSTest1Connected = false;
        private bool isSTest2Connected = false;
        FontIcon disconnectedIcon;
        FontIcon connectedIcon;
        private string stest1Name = "S-TEST 1";
        private string stest2Name = "S-TEST 2";

        public MainWindow()
        {
            this.InitializeComponent();

            // ...

            // Icon
            // Reference:https://stackoverflow.com/questions/34724792/how-to-programmatically-create-textblock-using-segoe-mdl2-assets-font-in-wpf

            disconnectedIcon = new FontIcon();
            disconnectedIcon.Glyph = "\uF78A";    // -> CancelMedium, unicode character code
            disconnectedIcon.FontFamily = new FontFamily("Segoe MDL2 Assets");
            //{
            //    Glyph = "\uF78A",    // -> CancelMedium, unicode character code
            //    //Glyph = "\xF78A",    // -> CancelMedium, hex character code
            //    //Glyph = "\xEB90",  // -> StatusErrorFull, hex character code
            //    FontFamily = new FontFamily("Segoe MDL2 Assets"),                
            //};

            connectedIcon = new FontIcon();
            connectedIcon.Glyph = "\uF78C";    // -> AcceptMedium, unicode character code
            connectedIcon.FontFamily = new FontFamily("Segoe MDL2 Assets");

            //{
            //    Glyph = "\uF78C",
            //    //Glyph = "\xF78C",    // -> AcceptMedium, hex character code
            //    //Glyph = "\xEC61",  // -> CompletedSolid, hex character code
            //    FontFamily = new FontFamily("Segoe MDL2 Assets"),
            //};

        }

        // Other methods...

        private void gyroConnectionButton_Click(object sender, RoutedEventArgs e)
        {
            if (isGyroConnected == true)
            {
                // Disconnect from gyro
                isGyroConnected = false;
                gyroConnectionButton.Label = "Disconnected";
                gyroConnectionButton.Icon = disconnectedIcon;
                //gyroConnectionButton.Content = "Disconnected";
                return;
            }

            // Connect to gyro
            isGyroConnected = true;
            gyroConnectionButton.Label = "Connected";
            gyroConnectionButton.Icon = connectedIcon;
            //gyroConnectionButton.Content = "Connected";
        }

        private async void stest1ConnectionButton_Click(object sender, RoutedEventArgs e)
        {
            if (isSTest1Connected == true)
            {
                // Disconnect from S-TEST 1
                isSTest1Connected = false;
                stest1ConnectionButton.Label = "Disconnected";
                stest1ConnectionButton.Icon = disconnectedIcon;
                //stest1ConnectionButton.Content = "Disconnected";
                return;
            }

            // Connect to S-TEST 1
            ContentDialog connectDialog = new ContentDialog
            {
                XamlRoot = Content.XamlRoot,
                Title = "Connect to S-TEST 1",
                Content = new StackPanel 
                {
                    Orientation = Orientation.Vertical,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment = VerticalAlignment.Center,
                    Children = 
                    {
                        new TextBlock { Text = "Name the S-TEST:" },
                        new TextBox { Name = "stest1NameTextBox", PlaceholderText = stest1Name },
                        new TextBlock { Text = "Enter the IP address of S-TEST:" },
                        new TextBox { Name = "stest1IP"}
                    },
                    Padding = new Thickness(5),
                },
                PrimaryButtonText = "Connect",
                CloseButtonText = "Cancel",
                DefaultButton = ContentDialogButton.Primary,
            };

            ContentDialogResult result = await connectDialog.ShowAsync();

            if (result == ContentDialogResult.Primary)
            {
                TextBox nameTextBox = (TextBox)((StackPanel)connectDialog.Content).Children[1];
                TextBox ipTextBox = (TextBox)((StackPanel)connectDialog.Content).Children[3];

                stest1Name = nameTextBox.Text.Trim();
                string ip = ipTextBox.Text.Trim();

                if (string.IsNullOrEmpty(ip) == false)
                {
                    // Connect to S-TEST 1
                    isSTest1Connected = true;
                    stest1ConnectionButton.Label = "Connected";
                    stest1ConnectionButton.Icon = connectedIcon;
                    //stest1ConnectionButton.Content = "Connected";

                    if (string.IsNullOrEmpty(stest1Name) == false)
                    {
                        stest1NameTextBlock.Text = stest1Name;
                    }
                }
            }
        }

        private async void stest2ConnectionButton_Click(object sender, RoutedEventArgs e)
        {
            if (isSTest2Connected == true)
            {
                // Disconnect from S-TEST 2
                isSTest2Connected = false;
                stest2ConnectionButton.Label = "Disconnected";
                stest2ConnectionButton.Icon = disconnectedIcon;
                //stest2ConnectionButton.Content = "Disconnected";
                return;
            }

            // Connect to S-TEST 2
            ContentDialog connectDialog = new ContentDialog
            {
                XamlRoot = Content.XamlRoot,
                Title = "Connect to S-TEST 2",
                Content = new StackPanel
                {
                    Orientation = Orientation.Vertical,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment = VerticalAlignment.Center,
                    Children =
                    {
                        new TextBlock { Text = "Name the S-TEST:" },
                        new TextBox { Name = "stest2NameTextBox", PlaceholderText = stest2Name },
                        new TextBlock { Text = "Enter the IP address of S-TEST:" },
                        new TextBox { Name = "stest2IP"}
                    },
                    Padding = new Thickness(5),
                },
                PrimaryButtonText = "Connect",
                CloseButtonText = "Cancel",
                DefaultButton = ContentDialogButton.Primary,
            };

            ContentDialogResult result = await connectDialog.ShowAsync();

            if (result == ContentDialogResult.Primary)
            {
                TextBox nameTextBox = (TextBox)((StackPanel)connectDialog.Content).Children[1];
                TextBox ipTextBox = (TextBox)((StackPanel)connectDialog.Content).Children[3];

                stest2Name = nameTextBox.Text.Trim();
                string ip = ipTextBox.Text.Trim();

                if (string.IsNullOrEmpty(ip) == false)
                {
                    // Connect to S-TEST 2
                    isSTest2Connected = true;
                    stest2ConnectionButton.Label = "Connected";
                    stest2ConnectionButton.Icon = connectedIcon;
                    //stest2ConnectionButton.Content = "Connected";

                    if (string.IsNullOrEmpty(stest2Name) == false)
                    {
                        stest2NameTextBlock.Text = stest2Name;
                    }
                }
            }
        }
    }
}

我知道的唯一信息是它有时会在进入

if-
块后发生:

if (result == ContentDialogResult.Primary)

有解决这个错误的方法吗?

c# icons winui-3 appbar contentdialog
1个回答
0
投票

通过使两个

AppBarButton.Icon
属性引用相同的
FontIcon
资源,可以稳定地再现它。您可以让每个
AppBarButton.Icon
都有自己的
FontIcon
资源。

© www.soinside.com 2019 - 2024. All rights reserved.