Bootstrap Blazor UI 库小技巧 (持续更新)
1. 文本处理键盘按键
<Bootstrap Blazorclass="table-toolbar-search" placeholder="@SearchPlaceholderText" @onkeyup="OnSearchKeyUp" @bind-Value="@SearchText">
</BootstrapInput>
@code{
private async Task OnSearchKeyUp(KeyboardEventArgs args)
{
if (args.Key == "Enter")
{
await SearchClick();
}
else if (args.Key == "Escape")
{
await ClearSearchClick();
}
}
}
2. 文本框逐字搜索
UseInputEvent: 是否在文本框输入值时触发 bind-value:event="oninput" 默认 false
<BootstrapInput @bind-Value="value" ShowLabel="true" UseInputEvent="true" />
@value
@code{
[DisplayName("条码文字")]
private string? value { get; set; } = "12345";
}
3. Ajaxs 请求处理参数大小写
private async Task ProcessResponse(string userName, string password)
{
var option = new AjaxOption()
{
Url = "/api/Login",
Data = new User() { UserName = userName, Password = password }
};
var result = await AjaxService.InvokeAsync(option);
if (result == null)
{
ResultMessage = "Login failed";
}
else
{
if (200 == result.RootElement.GetProperty("code").GetInt32())
{
await SwalService.Show(new SwalOption() { Content = "Login success!", Category = SwalCategory.Success });
}
else
{
await SwalService.Show(new SwalOption() { Content = $"Login failed: {result.RootElement.GetProperty("message").GetString()}", Category = SwalCategory.Error });
}
}
}
class User
{
[JsonPropertyName("uSErnaMe22222")]
public string? UserName { get; set; }
public string? Password { get; set; }
}
4. 文本框获取焦点事件(触摸屏应用)
<BootstrapInput ShowLabel="true"
@bind-Value="@one"
@onfocus="_=>OnFocus(0)"/>
<BootstrapInput ShowLabel="true"
@bind-Value="@two"
@onfocus="_=>OnFocus(1)"/>
<Button class="m-1" Text="abc" Color="Color.Success" OnClick='_=>OnKeyBoardsItemClick("abc")' />
<Button class="m-1" Text="def" Color="Color.Success" OnClick='_=>OnKeyBoardsItemClick("def")' />
@code{
string one="one";
string two = "two";
int mode;
private Task OnFocus(int v)
{
mode = v;
return Task.CompletedTask;
}
//触摸按钮点击
private Task OnKeyBoardsItemClick(string v)
{
switch (mode)
{
case 1:
two = v;
break;
default:
one = v;
break;
}
return Task.CompletedTask;
}
}
5. 模板取消链接默认点击事件
模板默认带了链接 <a href="#" 导致点击后回到主页, 如果要停留在当前页,需要取消事件的默认行为
https://www.jianshu.com/p/c933de9249c7
<Logout>
<LinkTemplate>
<a @onclick="@(e => IsOpen = !IsOpen)" @onclick:stopPropagation><i class="fa-solid fa-cog"></i>设置</a>
</LinkTemplate>
</Logout>
6. Segmented 超出宽度显示滚动条
<Segmented TValue="Dto" Items="@Items" class="over-x-bar-thin" />
.over-x-bar-thin {
width: 100%;
scrollbar-width: thin;
overflow-x: auto;
}
7. 制作无软键盘弹出焦点的输入框
<BootstrapInput inputmode="none"/>
8. 关闭点击表格行自定义操作按钮栏冒泡事件, 避免点击行事件执行
点击 PopConfirmButton 按钮不触发 OrderListItemClick
点击 Button 按钮不触发 OrderListItemClick
<Table OnClickRowCallback="OrderListItemClick">
<TableColumns>
<TableColumn>
<Template>
<div @onclick:stopPropagation="true">
<PopConfirmButton />
<Button />
</div>
</Template>
</TableColumn>
</TableColumns>
</Table>
9. 屏幕键盘组件技巧
BootstrapInput 绑定变量 int?, 这样没有默认值,比较清爽
不能带 FormatString , 不然会一直格式化,表现很糟糕
public int? PurchasePlan { get; set; }
<OnScreenKeyboard ClassName="virtualkeyboard" Option="Option1" />
<BootstrapInput @bind-Value="v.Row.PurchasePlan" class="virtualkeyboard" data-kioskboard-type="numpad" style="max-width:70px;" />
@code{
static Dictionary<string, string> keys1 = new Dictionary<string, string>() { { "0", "." } };
static List<Dictionary<string, string>> keysArray = new List<Dictionary<string, string>>() { keys1 };
KeyboardOption Option1 = new KeyboardOption()
{
keysArrayOfObjects = keysArray,
keysFontFamily = "Barlow",
keysFontWeight = "800",
keysAllowSpacebar=false
};
}
遇到需要输入小数情况,可以拆分为两个输入框分别绑定 int? 类型输入整数和小数,代码再合并数值.
@{
var pricePurchase = (v.Row as ResProductsPro).PricePurchase;
int? p1=null;
int? p2 = null;
if (v.Row.PricePurchasePlan == null && pricePurchase != 0)
{
p1 = (int)Math.Truncate(pricePurchase);
p2 = (int)((pricePurchase - Math.Truncate(pricePurchase)) * 100);
}
}
<BootstrapInput @bind-Value="v.Row.PricePurchasePlan" PlaceHolder="@p1.ToString()" class="virtualkeyboard" data-kioskboard-type="numpad" style="max-width:50px;" />
<BootstrapInputGroupLabel DisplayText="." />
<BootstrapInput @bind-Value="v.Row.PricePurchasePlan2" PlaceHolder="@p2.ToString()" class="virtualkeyboard" data-kioskboard-type="numpad" style="max-width:50px;" />
@code{
if (item.PricePurchasePlan != null || item.PricePurchasePlan2 != null)
{
item.PricePurchase = ((item.PricePurchasePlan ?? 0) + (item.PricePurchasePlan2 ?? 0) / 100);
}
}
10. JS组件
使用bb封装的js组件 JSModuleAutoLoader 可以达到事半功倍的效果,例如实现一个跟webview2交互
HybridMessage.razor
@namespace AmeTouch.Component
@inherits BootstrapModuleComponentBase
<span id="webMessageId" data="@Id" />
HybridMessage.razor.cs
[JSModuleAutoLoader("./_content/JovenRes.Shared/Component/HybridMessage.razor.js", JSObjectReference = true)]
public partial class HybridMessage
{
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop);
[JSInvokable]
public Task<string> WebMessage(string command, string arg)
{
return Task.FromResult("OK");
}
}
HybridMessage.razor.js
import Data from "../../BootstrapBlazor/modules/data.js"
export function init(id, invoke) {
const _invoke =invoke
Data.set(id, _invoke)
}
window.webMessage = function (cmd, message) {
const id = document.getElementById('webMessageId').getAttribute('data')
const invoke = Data.get(id)
invoke.invokeMethodAsync('WebMessage', cmd, message)
.then(data => {
console.log(data);
});
}
export function dispose(id) {
const invoke = Data.get(id)
Data.remove(id)
}
wpf webview2交互
public MainWindow()
{
InitializeComponent();
this.StateChanged += async (s, e) => await MainWindow_StateChangedAsync();
private async Task MainWindow_StateChangedAsync()
{
await webView.ExecuteScriptAsync($"webMessage('windowStateChanged','{this.WindowState}')");
}
}
关联项目
FreeSql QQ群:4336577
BA & Blazor QQ群:795206915
Maui Blazor 中文社区 QQ群:645660665
知识共享许可协议
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名AlexChow(包含链接: https://github.com/densen2014 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系 。
转载声明
本文来自博客园,作者:周创琳 AlexChow,转载请注明原文链接:https://www.cnblogs.com/densen2014/p/17893164.html