次の方法で共有


ASP.NET Core Blazor Hybrid でルート コンポーネントのパラメーターを渡す

注意

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。

警告

このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。

重要

この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。

現在のリリースについては、この記事の .NET 9 バージョンを参照してください。

この記事では、Blazor Hybrid アプリでルート コンポーネントのパラメーターを渡す方法について説明します。

BlazorWebViewRootComponent クラスで定義されている IDictionary<string, object?>? 型の Parameters プロパティは、ルート コンポーネントに渡すパラメーターの省略可能なディクショナリを表します。

次の例では、ビュー モデルをルート コンポーネントに渡し、そこからさらに、ビュー モデルをカスケード型としてアプリの Blazor 部分の Razor コンポーネントに渡します。 この例は、.NET MAUI のドキュメントのキーパッドの例に基づいています。

キーパッドの例の対象は、.NET MAUIBlazor Hybrid アプリでの MVVM パターンの実装ですが:

  • アプリの Razor コンポーネントで使うために 1 つ以上のパラメーターをルート コンポーネントに渡す必要がある場合、ルート コンポーネントに渡されるオブジェクトのディクショナリに、任意の目的で任意の型を含めることができます。
  • 次の .NET MAUIBlazor の例で示されている概念は、Windows フォーム Blazor アプリと WPF Blazor アプリでも同じです。

次のビュー モデルを .NET MAUIBlazor Hybrid アプリに配置します。

KeypadViewModel.cs:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;

namespace MauiBlazor;

public class KeypadViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _inputString = "";
    private string _displayText = "";
    private char[] _specialChars = { '*', '#' };

    public ICommand AddCharCommand { get; private set; }
    public ICommand DeleteCharCommand { get; private set; }

    public string InputString
    {
        get => _inputString;
        private set
        {
            if (_inputString != value)
            {
                _inputString = value;
                OnPropertyChanged();
                DisplayText = FormatText(_inputString);

                // Perhaps the delete button must be enabled/disabled.
                ((Command)DeleteCharCommand).ChangeCanExecute();
            }
        }
    }

    public string DisplayText
    {
        get => _displayText;
        set
        {
            if (_displayText != value)
            {
                _displayText = value;
                OnPropertyChanged();
            }
        }
    }

    public KeypadViewModel()
    {
        // Command to add the key to the input string
        AddCharCommand = new Command<string>((key) => InputString += key);

        // Command to delete a character from the input string when allowed
        DeleteCharCommand =
            new Command(
                // Command strips a character from the input string
                () => InputString = InputString.Substring(0, InputString.Length - 1),

                // CanExecute is processed here to return true when there's something to delete
                () => InputString.Length > 0
            );
    }

    string FormatText(string str)
    {
        bool hasNonNumbers = str.IndexOfAny(_specialChars) != -1;
        string formatted = str;

        // Format the string based on the type of data and the length
        if (hasNonNumbers || str.Length < 4 || str.Length > 10)
        {
            // Special characters exist, or the string is too small or large for special formatting
            // Do nothing
        }

        else if (str.Length < 8)
            formatted = string.Format("{0}-{1}", str.Substring(0, 3), str.Substring(3));

        else
            formatted = string.Format("({0}) {1}-{2}", str.Substring(0, 3), str.Substring(3, 3), str.Substring(6));

        return formatted;
    }

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

この記事の例では、アプリのルート名前空間は MauiBlazor です。 KeypadViewModel の名前空間を、アプリのルート名前空間と一致するように変更します。

namespace MauiBlazor;

Note

KeypadViewModel ビュー モデルが .NET MAUI サンプル アプリと .NET MAUI ドキュメント用に作成された時点では、ビュー モデルは ViewModels という名前のフォルダーに配置されましたが、名前空間はアプリのルートに設定され、フォルダー名を含んでいませんでした。 KeypadViewModel.cs ファイルでフォルダーを含むように名前空間を更新したい場合は、この記事のコード例を一致するように変更します。 using (C#) と @using (Razor) ステートメントを次のファイルに追加するか、ビュー モデル型への参照を {APP NAMESPACE}.ViewModels.KeypadViewModel として完全修飾します。{APP NAMESPACE} プレースホルダーはアプリのルート名前空間です。

Parameters は XAML で直接設定できますが、次の例では XAML ファイルでルート コンポーネントに名前を付けて (rootComponent)、分離コード ファイルでパラメーター ディクショナリを設定しています。

MainPage.xaml:

<RootComponent x:Name="rootComponent" 
               Selector="#app" 
               ComponentType="{x:Type local:Main}" />

分離コード ファイル (MainPage.xaml.cs) において、コンストラクターでビュー モデルを割り当てます。

public MainPage()
{
    InitializeComponent();

    rootComponent.Parameters = 
        new Dictionary<string, object>
        {
            { "KeypadViewModel", new KeypadViewModel() }
        };
}

次の例では、オブジェクト (KeypadViewModel) をアプリの Blazor 部分のコンポーネント階層の下方に CascadingValue としてカスケードします。

Main コンポーネント (Main.razor) 内は、次のようになっています。

  • ルート コンポーネントに渡されるオブジェクトの型と一致するパラメーターを追加します。

    @code {
        [Parameter]
        public KeypadViewModel KeypadViewModel { get; set; }
    }
    
  • CascadingValue コンポーネントKeypadViewModel をカスケードします。 <Found> XAML の内容を次のマークアップに更新します。

    <Found Context="routeData">
        <CascadingValue Value="KeypadViewModel">
            <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
            <FocusOnNavigate RouteData="routeData" Selector="h1"/>
        </CascadingValue>
    </Found>
    

この時点で、アプリ全体の Razor コンポーネントで、カスケードされた型を CascadingParameter として使用できます。

次の Keypad コンポーネントの例では:

  • KeypadViewModel.DisplayText の現在の値を表示します。
  • 表示文字列の長さが 0 (ゼロ) より大きい場合、KeypadViewModel.DeleteCharCommand コマンドを呼び出して文字を削除できるようにします。これは、ICommand.CanExecute の呼び出しによってチェックされます。
  • KeypadViewModel.AddCharCommand を呼び出すことにより、UI で押されてキーを使って文字を追加できるようにします。

Pages/Keypad.razor:

@page "/keypad"

<h1>Keypad</h1>

<table id="keypad">
    <thead>
        <tr>
            <th colspan="2">@KeypadViewModel.DisplayText</th>
            <th><button @onclick="DeleteChar">&#x21E6;</button></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><button @onclick="@(e => AddChar("1"))">1</button></td>
            <td><button @onclick="@(e => AddChar("2"))">2</button></td>
            <td><button @onclick="@(e => AddChar("3"))">3</button></td>
        </tr>
        <tr>
            <td><button @onclick="@(e => AddChar("4"))">4</button></td>
            <td><button @onclick="@(e => AddChar("5"))">5</button></td>
            <td><button @onclick="@(e => AddChar("6"))">6</button></td>
        </tr>
        <tr>
            <td><button @onclick="@(e => AddChar("7"))">7</button></td>
            <td><button @onclick="@(e => AddChar("8"))">8</button></td>
            <td><button @onclick="@(e => AddChar("9"))">9</button></td>
        </tr>
        <tr>
            <td><button @onclick="@(e => AddChar("*"))">*</button></td>
            <td><button @onclick="@(e => AddChar("0"))">0</button></td>
            <td><button @onclick="@(e => AddChar("#"))">#</button></td>
        </tr>
    </tbody>
</table>

@code {
    [CascadingParameter]
    protected KeypadViewModel KeypadViewModel { get; set; }

    private void DeleteChar()
    {
        if (KeypadViewModel.DeleteCharCommand.CanExecute(null))
        {
            KeypadViewModel.DeleteCharCommand.Execute(null);
        }
    }

    private void AddChar(string key)
    {
        KeypadViewModel.AddCharCommand.Execute(key);
    }
}

デモのためにのみ、wwwroot/index.html ファイルの <head> の内容に次の CSS スタイルを配置して、ボタンのスタイルを設定します。

<style>
    #keypad button {
        border: 1px solid black;
        border-radius:6px;
        height: 35px;
        width:80px;
    }
</style>

次のマークアップを使用して、NavMenu コンポーネント (Shared/NavMenu.razor) にサイド バー ナビゲーションのエントリを作成します。

<div class="nav-item px-3">
    <NavLink class="nav-link" href="keypad">
        <span class="oi oi-list-rich" aria-hidden="true"></span> Keypad
    </NavLink>
</div>

その他のリソース