如何使用MudSelect下拉框触发一个方法?

huangapple go评论102阅读模式
英文:

How do I trigger a method with MudSelect dropdown?

问题

我必须在每次变量`_selectedManufacturer`更改时触发此方法`OnManufacturerChanged()`。

有没有办法可以做到这一点?`Onclick`不起作用,`OnClose`在关闭后经过2次工作,等等,我尝试了许多方法。
英文:
<MudSelect T="ManufacturerDto" Label="Select Manufacturer" @bind-Value="_selectedManufacturer" Variant="Variant.Outlined">
         @foreach (var manufacturer in _filteredManufacturers)
         {
             <MudSelectItem T="ManufacturerDto"  Value="@manufacturer">@manufacturer.ManufacturerName</MudSelectItem>
         }
</MudSelect>

I have to trigger this method OnManufacturerChanged() each time a variable _selectedManufacturer has been changed.

Is there any way I can do this? Onclick doesn't work, OnClose works after 2 closing and etc, I tried many ways.

答案1

得分: 2

先决条件

为了使数据绑定起作用,必须满足以下两个条件:

  • 一个参数 {Name}(在您的情况下为 Value)必须是某种类型 T
  • 一个方法 {Name}Changed() 必须是类型 EventCallback<T>(在您的情况下为 ValueChanged

然后,Blazor会在您使用 @bind-Value 定义绑定并且值更改时,处理传递参数并为您调用此回调函数。所以没有什么神奇的地方。因此,考虑到这一点,您有不同的选择。您选择哪种方式取决于您的.NET版本和用例。

我将在一个简单的示例中概述所有这些方法,在这个示例中,我只是在值更改后将新的选择值记录到控制台。

如果您查看 <MudSelect /> 组件的API,您将看到这两个东西都为您提供了。

手动实现绑定

除了使用自动绑定之外,您当然也可以手动提供上面提到的这两个东西,并相应地处理它们。这会看起来像这样:

<MudSelect T="string" 
           Label="Manufacturer" 
           AnchorOrigin="Origin.BottomCenter"
           Value=@_selectedManufacturer
           ValueChanged=@OnManufacturerChanged>
    @foreach (var manufacturer in _allManufacturers)
    {   
        <MudSelectItem Value=@manufacturer>
            @manufacturer
        </MudSelectItem>
    }
</MudSelect>

@code {
    private List<string> _allManufacturers = new List<string>() 
    {
        "A",
        "B",
        "C"
    };
    private string _selectedManufacturer = String.Empty;

    private void OnManufacturerChanged(string manufacturer){
        _selectedManufacturer = manufacturer; // 更新选定的制造商
        Console.WriteLine($"制造商已更改为 '{_selectedManufacturer}'");
    }
}

优点

  • 允许在 ValueChanged 处理程序(这里是 OnManufacturerChanged)中使用异步调用
  • 可以访问先前的值

缺点

  • 需要更多的手动设置,因为无法使用内置的绑定

使用setter

当然,您也可以使用内置的绑定,然后在setter中触发一些功能,这意味着您必须使用一个属性。

<MudSelect T="string" 
           Label="Manufacturer" 
           AnchorOrigin="Origin.BottomCenter"
           @bind-Value=@SelectedManufacturer>
    @foreach (var manufacturer in _allManufacturers)
    {   
        <MudSelectItem Value=@manufacturer>
            @manufacturer
        </MudSelectItem>
    }
</MudSelect>

@code {
    private List<string> _allManufacturers = new List<string>() 
    {
        "A",
        "B",
        "C"
    };
    private string _selectedManufacturer = String.Empty;
    private string SelectedManufacturer {
        get { return _selectedManufacturer; }
        set {
            _selectedManufacturer = value;
            Console.WriteLine($"制造商已更改为 '{_selectedManufacturer}'");
        }
    }
}

优点

  • 使用内置数据绑定
  • 可以访问先前的值

缺点

  • 无法使用异步操作
  • 无法使用自动属性

@bind:after 用于 .NET 7 及以上版本

在.NET 7及更高版本中,您可以使用 @bind:after 来在绑定的值发生更改后触发某个函数。因此,以下内容将起作用:

<MudSelect T="string" 
           Label="Manufacturer" 
           AnchorOrigin="Origin.BottomCenter"
           @bind-Value=@_selectedManufacturer
           @bind-Value:after=@AfterManufacturerChanged>
    @foreach (var manufacturer in _allManufacturers)
    {   
        <MudSelectItem Value=@manufacturer>
            @manufacturer
        </MudSelectItem>
    }
</MudSelect>

@code {
    private List<string> _allManufacturers = new List<string>() 
    {
        "A",
        "B",
        "C"
    };
    private string _selectedManufacturer = String.Empty;

    private void AfterManufacturerChanged(){
        Console.WriteLine($"制造商已更改为 '{_selectedManufacturer}'");
    }
}

优点

  • 使用内置数据绑定
  • 无需额外设置,只需定义 @bind:after=要执行的方法
  • 可以与异步操作一起使用

缺点

  • 在绑定发生后调用方法时,无法直接访问先前的值
英文:

Pre-requistite

In order for data binding to work there have to be two things in place:

  • A parameter {Name} (in your case Value) of a certain type T
  • a method {Name}Changed() which is of type EventCallback&lt;T&gt;(in your case ValueChanged)

Blazor then handles passing the parameter and invoking this callback for you once you define the binding using @bind-Value and the value changes. So there is no magic. So with that in mind you have different options available. Which one you pick depends on your .NET version and use case.

I will outline all of those methods on a simple example where I just log the new select value to the console after it has changed.

> If you have a look at the API of the &lt;MudSelect /&gt; component you will see those two things are provided for you.

Manually implement binding

Instead of using the automatic binding you can of course also just supply the two things (mentioned above) manually and handle them accordingly. This would look something like this:

&lt;MudSelect T=&quot;string&quot; 
           Label=&quot;Manufacturer&quot; 
           AnchorOrigin=&quot;Origin.BottomCenter&quot;
           Value=@_selectedManufacturer
           ValueChanged=@OnManufacturerChanged&gt;
    @foreach (var manufacturer in _allManufacturers)
    {   
        &lt;MudSelectItem Value=@manufacturer&gt;
            @manufacturer
        &lt;/MudSelectItem&gt;
    }
&lt;/MudSelect&gt;

@code {
    private List&lt;string&gt; _allManufacturers = new List&lt;string&gt;() 
    {
        &quot;A&quot;,
        &quot;B&quot;,
        &quot;C&quot;
    };
    private string _selectedManufacturer = String.Empty;

    private void OnManufacturerChanged(string manufacturer){
        _selectedManufacturer = manufacturer; // update selected manufacturer
        Console.WriteLine($&quot;Manufacturer has changed to &#39;{_selectedManufacturer}&#39;&quot;);
    }
}

Pros

  • Allows to use asynchronous calls in the ValueChanged handler (Here OnManufacturerChanged)
  • Access to previous value

Cons

  • More manual setup required, since built-in binding cannot be used

Using setter

Of course you can also use the built-in binding and then trigger some functionality in the setter which implies that you have to use a property.

&lt;MudSelect T=&quot;string&quot; 
           Label=&quot;Manufacturer&quot; 
           AnchorOrigin=&quot;Origin.BottomCenter&quot;
           @bind-Value=@SelectedManufacturer&gt;
    @foreach (var manufacturer in _allManufacturers)
    {   
        &lt;MudSelectItem Value=@manufacturer&gt;
            @manufacturer
        &lt;/MudSelectItem&gt;
    }
&lt;/MudSelect&gt;

@code {
    private List&lt;string&gt; _allManufacturers = new List&lt;string&gt;() 
    {
        &quot;A&quot;,
        &quot;B&quot;,
        &quot;C&quot;
    };
    private string _selectedManufacturer = String.Empty;
    private string SelectedManufacturer {
        get { return _selectedManufacturer; }
        set {
            _selectedManufacturer = value;
            Console.WriteLine($&quot;Manufacturer has changed to &#39;{_selectedManufacturer}&#39;&quot;);
        }
    }
}

Pros

  • Uses built-in data binding
  • Access to previous value

Cons

  • Cannot use asynchronous operations
  • Cannot use auto-properties

@bind:after for >= .NET 7

On .NET 7 you can use @bind:after to trigger some function after a value in a binding has changed. So the following will work:

&lt;MudSelect T=&quot;string&quot; 
           Label=&quot;Manufacturer&quot; 
           AnchorOrigin=&quot;Origin.BottomCenter&quot;
           @bind-Value=@_selectedManufacturer
           @bind-Value:after=@AfterManufacturerChanged&gt;
    @foreach (var manufacturer in _allManufacturers)
    {   
        &lt;MudSelectItem Value=@manufacturer&gt;
            @manufacturer
        &lt;/MudSelectItem&gt;
    }
&lt;/MudSelect&gt;

@code {
    private List&lt;string&gt; _allManufacturers = new List&lt;string&gt;() 
    {
        &quot;A&quot;,
        &quot;B&quot;,
        &quot;C&quot;
    };
    private string _selectedManufacturer = String.Empty;

    private void AfterManufacturerChanged(){
        Console.WriteLine($&quot;Manufacturer has changed to &#39;{_selectedManufacturer}&#39;&quot;);
    }
}

Pros

  • Uses built-in data binding
  • No extra setup required, just define @bind:after=MethodToExecute
  • Works with asynchronous operations

Cons

  • No direct access to previous value in method being invoke after the binding has occurred

huangapple
  • 本文由 发表于 2023年8月4日 23:28:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76837318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定