WinUI3 除錯模式時動態建立按鈕

平時在開發時有些功能需要反覆測試,希望會先做幾個按鈕來協助我們測試功能,但是發布時又要再把它移除,這樣要一直改程式碼很麻煩,這個時候就可以使用到「條件式編譯」。

假設我們在畫面上有一個用於計算數字的 TextBlock,一個 Button 按下後會將數字增加:
    
<Page
    x:Class="WinUi3ConditionalCompilationTest.Page1"
    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"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBlock x:Name="TextBlock" Text="0" />
        <Button x:Name="AddButton">Add</Button>
    </StackPanel>
    
</Page>
    

程式碼部分如下:
    
public sealed partial class Page1 : Page
{
    public Page1()
    {
        this.InitializeComponent();

        int count = 0;
        AddButton.Click += (_, _) => TextBlock.Text = ++count + ""; // 數字 +1 並顯示
    }
}
    

假設我們只有開放給使用者增加數字的功能,可能還會將資料寫入設定檔中,而因為我們要反覆測試,可能要去設定檔中將數字歸零,然後再次測試,很繁瑣。

我們可以使用條件式編譯的功能,如果是除錯模式,就在畫面載入完成後動態的在 Add 的按鈕後面加一個重設的按鈕,這樣就可以方便測試,在發布時按鈕也不會被加上去:
    
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;


public sealed partial class Page1 : Page
{
    public Page1()
    {
        this.InitializeComponent();


        int count = 0;
        AddButton.Click += (_, _) => TextBlock.Text = ++count + "";

#if DEBUG
        Loaded += (_, _) =>
        {
            var resetButton = new Button
            {
                Content = new SymbolIcon(Symbol.Refresh),
                HorizontalAlignment = HorizontalAlignment.Right,
                FontSize = 4,
            };
            resetButton.Click += (sender, args) =>
            {
                count = 0;
                TextBlock.Text = count + "";
            };

            if (AddButton.Parent is StackPanel stackPanel)
            {
                var index = stackPanel.Children.IndexOf(AddButton);
                stackPanel.Children.Insert(index + 1, resetButton);
                    
            }
        };
#endif
            
    }
}
    


註: 在 Page 中才有 Loaded 事件,在 MainWindow 中不存在。 在 #if DEBUG 區塊的程式碼在發布時是不會執行到的,非常方便
    
#if DEBUG

// 只有在除錯模式時才會執行

#endif
    


補充:
如果要在 MainWindow.xaml 上顯示 Page 可以這樣:
    
<Frame x:Name="MainFrame" SourcePageType="local:Page1" />
    



參考資料:
Microsoft.Learn - C# preprocessor directives

留言