XAMLで始めるWPF入門:過去一シンプルなユーザーコントロールのサンプルコード。その2

コンピュータ

今回はXAMLとの組み合わせで、データバインディングを行うコードにしてみました。

ソースコード

ファイル名:App.xaml

<Application x:Class="UserControlSampe.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:UserControlSampe"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

ファイル名:App.xaml.cs

using System.Configuration;
using System.Data;
using System.Windows;

namespace UserControlSampe;

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}


ファイル名:MainWindow.xaml

<Window x:Class="UserControlSampe.MainWindow"
        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"
        xmlns:local="clr-namespace:UserControlSampe"
        mc:Ignorable="d"

        xmlns:controls="clr-namespace:Maywork.WPF.Controls"

        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <controls:MiniLabel Text="{Binding SomeLabelText}" InitFontSize="32" />
        <!-- SomeLabelText は Window の DataContext のプロパティ -->
    </StackPanel>
</Window>

ファイル名:MainWindow.xaml.cs

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;

namespace UserControlSampe;

public partial class MainWindow : Window , INotifyPropertyChanged
{
    string _someLabelText = "";
    public string SomeLabelText
    {
        get => _someLabelText;
        set
        {
            if (_someLabelText == value) return;
            _someLabelText = value;
            OnPropertyChanged();
        }
    }
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        this.Loaded += (_, __) =>
        {
            SomeLabelText = "こちらの文字列が表示される。";
        };
        this.MouseDoubleClick += (_, __) =>
        {
            SomeLabelText = "ダウブルクリックで文字列が変化";
        };
    }
    public event PropertyChangedEventHandler? PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string? name = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

ファイル名:UserControls\MiniLabel.cs

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;


namespace Maywork.WPF.Controls;

public partial class MiniLabel : UserControl
{
    public MiniLabel()
    {
        InitializeComponent();

        // ロード後
        Loaded += (_, _) => Apply();
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register(
            nameof(Text),
            typeof(string),
            typeof(MiniLabel),
            new PropertyMetadata(string.Empty));

    // DP。バインド可能
    public string Text
    {
        get => (string)GetValue(TextProperty);
        set => SetValue(TextProperty, value);
    }
    
    // 通常のプロパティ。初期化のみしか出来ない。
    public string InitFontSize { get; set; } = "";

    void Apply()
    {
        Label1.FontSize = double.TryParse(InitFontSize, out var v) ? v : 10;
    }
}

ファイル名:UserControls\MiniLabel.xaml

<UserControl x:Class="Maywork.WPF.Controls.MiniLabel"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <TextBlock
            x:Name="Label1"
            Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    </Grid>
</UserControl>

ファイル名:UserControlSampe.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net10.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

</Project>

実行例

起動時の状態

ダブルクリック後

コメント