为blazor创建三态复选框组件



<input @bind="Checked" type="checkbox" @onclick="eventArgs => { onclick(); }" indeterminate="@indeterminate" class="checkbox-input">
@code {
[Parameter]
public bool? selected { get; set; } = null;
public bool indeterminate { get; set; }
public bool Checked { get; set; }
public void onclick()
{

selected = selected == null ? true : selected == true ? new bool?() : false;

Checked = selected == null || selected == false;
indeterminate = selected == null;
}
}

这不会产生所需的结果

复选框始终处于选中或未选中状态,从不确定。

有什么想法吗?

我在.NET核心3.1+中实现了这个简单的组件。这是一把小提琴。

css来自bootstrap,需要显示一个空框、一个选中框和一个框;"满";表示状态0,1,-1(可以很容易地更改这些值(:

<style>
[class^="icon-"], [class*=" icon-"] { display: inline-block; width: 14px; height: 14px; margin-top: 1px; *margin-right: .3em; line-height: 14px; vertical-align: text-top; background-image: url(/img/glyphicons-halflings.png); background-position: 14px 14px; background-repeat: no-repeat; }
.bootstrap-checkbox { display: inline-block; position: relative; width: 13px; height: 13px; border: 1px solid #000; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
.bootstrap-checkbox i { position: absolute; left: -2px; top: -3px; }
.icon-stop { background-position: -312px -72px; }
.icon-check { background-position: -288px 0px; }
</style>

这就是blazor组件:

<div @ref=checkboxElement class="bootstrap-checkbox" @onclick="(e) => OnClick(e)"><i class="@ImgClass"></i></div>@Description
@code {
public ElementReference checkboxElement { get; set; }
[Parameter]
public string Description { get; set; }
[Parameter]
public bool? Checked { get; set; }
public string ImgClass { get; set; }
public int Value { get; set; }
protected override void OnInitialized()
{
Value = Checked switch { null => -1, true => 1, false => 0 };
ImgClass = Value switch { -1 => "icon-stop", 1 => "icon-check", _ => "" };
}
public void OnClick(MouseEventArgs e)
{
switch (ImgClass)
{
case "":
ImgClass = "icon-check";
Value = 1;
break;
case "icon-check":
ImgClass = "icon-stop";
Value = -1;
break;
case "icon-stop":
ImgClass = "";
Value = 0;
break;
}
}
}

使用JS interop

创建一个简单的脚本

<script>
var auxiliarDOM = auxiliarDOM || {};
auxiliarDOM.setValue = function (element, property,value) {
element[property] = value;
}
</script>

然后在blazor你可以有一个ElementRef

@inject IJSRuntime JSRuntime
<input @ref="checkRef" type="checkbox" />
private ElementReference checkRef;
//this make the check indeterminate
await JSRuntime.InvokeVoidAsync("auxiliarDOM.setValue", checkRef, "indeterminate", true);
//this make the check no indeterminate
await JSRuntime.InvokeVoidAsync("auxiliarDOM.setValue", checkRef, "indeterminate", false);

三态复选框组件,基于Eliseo的答案:

工作示例:Blazor fiddle

JS设置indeterminate属性:

<script type="text/javascript">
function setElementProperty(element, property, value) {
element[property] = value;
}
</script>

CheckBox.razor文件:

<input @ref=elementRef id="@elementId" type="checkbox" checked="@isChecked" @onchange="OnChange"/>
<label for="@elementId">@ChildContent</label>

CheckBox.razor.cs文件:

using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System;
using System.Threading.Tasks;
public partial class CheckBox
{
[Inject]
IJSRuntime jsRuntime { get; set; } = null!;
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public bool? Checked { get; set; }
[Parameter]
public EventCallback<bool?> CheckedChanged { get; set; }
private bool isChecked;
private ElementReference elementRef;
private string elementId = Guid.NewGuid().ToString();
private async Task OnChange(ChangeEventArgs e)
{
Checked = Checked switch
{
false => true,
true => null,
null => false,
};
isChecked = Checked != false;
bool indet = Checked == null;
await jsRuntime.InvokeVoidAsync("setElementProperty", elementRef, "indeterminate", indet);
await CheckedChanged.InvokeAsync(Checked);
}
}

最新更新