英文:
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 caseValue
) of a certain typeT
- a method
{Name}Changed()
which is of typeEventCallback<T>
(in your caseValueChanged
)
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 <MudSelect />
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:
<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; // update selected manufacturer
Console.WriteLine($"Manufacturer has changed to '{_selectedManufacturer}'");
}
}
Pros
- Allows to use asynchronous calls in the
ValueChanged
handler (HereOnManufacturerChanged
) - 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.
<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($"Manufacturer has changed to '{_selectedManufacturer}'");
}
}
}
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:
<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($"Manufacturer has changed to '{_selectedManufacturer}'");
}
}
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论