Skip to content

Commit 39659e4

Browse files
committed
2 parents 304e26e + db56431 commit 39659e4

File tree

9 files changed

+90
-21
lines changed

9 files changed

+90
-21
lines changed

src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
<PackageReference Include="BootstrapBlazor.OctIcon" Version="9.0.4" />
6161
<PackageReference Include="BootstrapBlazor.OfficeViewer" Version="9.0.0" />
6262
<PackageReference Include="BootstrapBlazor.OnScreenKeyboard" Version="9.0.1" />
63-
<PackageReference Include="BootstrapBlazor.OpcDa" Version="9.0.0" />
63+
<PackageReference Include="BootstrapBlazor.OpcDa" Version="9.0.1" />
6464
<PackageReference Include="BootstrapBlazor.PdfReader" Version="9.0.1" />
6565
<PackageReference Include="BootstrapBlazor.PdfViewer" Version="9.0.6" />
6666
<PackageReference Include="BootstrapBlazor.Player" Version="9.0.1" />

src/BootstrapBlazor.Server/Components/Samples/OpcDa.razor

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<PackageTips Name="BootstrapBlazor.OpcDa"/>
99

10-
<DemoBlock Title="@Localizer["OpcDaNormalTitle"]" Introduction="@Localizer["OpcDaNormalIntro"]" Name="Normal">
10+
<DemoBlock Title="@Localizer["OpcDaNormalTitle"]" Introduction="@Localizer["OpcDaNormalIntro"]" ShowCode="false" Name="Normal">
1111
<p class="code-label">1. 点击 <b>连接</b> 按钮与 <code>OpcDa</code> 服务器建立通讯连接</p>
1212
<p>
1313
<BootstrapInputGroup>
@@ -42,7 +42,7 @@
4242

4343
<p class="code-label">3. 订阅功能</p>
4444
<p>通过订阅可以监控一组 <b>位号</b> 数据改变情况,当数据改变时通过 <code>DataChanged</code> 回调方法通知订阅者</p>
45-
<div class="row g-3">
45+
<p class="row g-3">
4646
<div class="col-12 col-sm-6">
4747
<BootstrapInputGroup>
4848
<BootstrapInputGroupLabel DisplayText="订阅名称"></BootstrapInputGroupLabel>
@@ -73,5 +73,15 @@
7373
<Button OnClick="OnCreateSubscription" Text="订阅" IsDisabled="@(!OpcDaServer.IsConnected || _subscribed)"></Button>
7474
<Button OnClick="OnCancelSubscription" Text="取消" IsDisabled="!_subscribed"></Button>
7575
</div>
76-
</div>
76+
</p>
77+
78+
<p class="code-label">4. 浏览</p>
79+
<p>通过调用 <code>OpcDaServer</code> 的 <code>Browse</code> 方法可以构建一个节点树状结构</p>
80+
<p>
81+
<Button OnClick="OnBrowse" Text="浏览" IsDisabled="!OpcDaServer.IsConnected"></Button>
82+
</p>
83+
<p>
84+
<TreeView Items="_roots" AutoCheckChildren="true" AutoCheckParent="true" ShowIcon="true"
85+
OnExpandNodeAsync="OnExpandNodeAsync"></TreeView>
86+
</p>
7787
</DemoBlock>

src/BootstrapBlazor.Server/Components/Samples/OpcDa.razor.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,33 @@ private void UpdateValues(List<OpcReadItem> items)
8282

8383
InvokeAsync(StateHasChanged);
8484
}
85-
}
8685

86+
private List<TreeViewItem<OpcBrowseElement>> _roots = [];
87+
88+
private void OnBrowse()
89+
{
90+
var elements = OpcDaServer.Browse("", new OpcBrowseFilters(), out _);
91+
_roots = elements.Select(element => new TreeViewItem<OpcBrowseElement>(element)
92+
{
93+
Text = element.Name,
94+
HasChildren = element.HasChildren,
95+
Icon = "fa-solid fa-fw fa-cubes"
96+
}).ToList();
97+
}
98+
99+
private Task<IEnumerable<TreeViewItem<OpcBrowseElement>>> OnExpandNodeAsync(TreeViewItem<OpcBrowseElement> element)
100+
{
101+
var children = OpcDaServer.Browse(element.Value.ItemName, new OpcBrowseFilters(), out _);
102+
var items = children.Select(i => new TreeViewItem<OpcBrowseElement>(i)
103+
{
104+
Text = i.Name,
105+
HasChildren = i.HasChildren,
106+
Icon = i.HasChildren ? "fa-solid fa-fw fa-cube" : "fa-solid fa-fw fa-wrench"
107+
});
108+
if (!items.Any())
109+
{
110+
element.HasChildren = false;
111+
}
112+
return Task.FromResult(items);
113+
}
114+
}

src/BootstrapBlazor/BootstrapBlazor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.9.1</Version>
4+
<Version>9.9.2-beta03</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Components/Download/Download.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See the LICENSE file in the project root for more information.
44
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
55

6+
using System;
7+
68
namespace BootstrapBlazor.Components;
79

810
/// <summary>
@@ -38,13 +40,13 @@ protected virtual async Task DownloadFromStream(DownloadOption option)
3840
throw new InvalidOperationException($"the {nameof(option.FileStream)} is null");
3941
}
4042

41-
#if NET5_0
42-
// net 5.0 not support
43-
await Task.CompletedTask;
44-
#elif NET6_0_OR_GREATER
43+
if (string.IsNullOrEmpty(option.FileName))
44+
{
45+
throw new InvalidOperationException($"the {nameof(option.FileName)} is null or empty");
46+
}
47+
4548
using var streamRef = new DotNetStreamReference(option.FileStream);
4649
await InvokeVoidAsync("downloadFileFromStream", option.FileName, streamRef);
47-
#endif
4850
}
4951

5052
/// <summary>
@@ -59,6 +61,11 @@ protected virtual async Task DownloadFromUrl(DownloadOption option)
5961
throw new InvalidOperationException($"{nameof(option.Url)} not set");
6062
}
6163

64+
if (string.IsNullOrEmpty(option.FileName))
65+
{
66+
throw new InvalidOperationException($"the {nameof(option.FileName)} is null or empty");
67+
}
68+
6269
await InvokeVoidAsync("downloadFileFromUrl", option.FileName, option.Url);
6370
}
6471

src/BootstrapBlazor/Components/Dropdown/Dropdown.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
}
1010
<div @attributes="@AdditionalAttributes" id="@Id" class="@DirectionClassName">
1111
<DynamicElement TagName="button" type="button" class="@ButtonClassName" data-bs-toggle="@DropdownToggle" disabled="@Disabled"
12-
TriggerClick="ShowSplit" OnClick="OnClickButton">
12+
TriggerClick="ShowSplit" OnClick="OnClickButton" PreventDefault="false" StopPropagation="false">
1313
@if (ButtonTemplate == null)
1414
{
1515
@if (_isAsyncLoading)

src/BootstrapBlazor/Components/Table/TableExtensionButton.razor

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@
1010
{
1111
case TableCellButton { IsShow: true } b:
1212
<Button AdditionalAttributes="b.AdditionalAttributes" Size="b.Size"
13-
Color="@b.Color" Icon="@b.Icon" Text="@b.Text" IsAsync="@b.IsAsync"
14-
TooltipText="@b.TooltipText" TooltipPlacement="@b.TooltipPlacement" TooltipTrigger="@b.TooltipTrigger"
15-
ChildContent="@b.ChildContent"
13+
Color="@b.Color" Icon="@b.Icon" Text="@b.Text"
14+
IsAsync="@b.IsAsync" IsKeepDisabled="b.IsKeepDisabled"
15+
TooltipText="@b.TooltipText" TooltipPlacement="@b.TooltipPlacement"
16+
TooltipTrigger="@b.TooltipTrigger" ChildContent="@b.ChildContent"
1617
OnClickWithoutRender="() => OnClick(b)" IsDisabled="b.IsDisabled"></Button>
1718
break;
1819
case TableCellPopConfirmButton { IsShow: true } pb:
1920
<PopConfirmButton AdditionalAttributes="pb.AdditionalAttributes"
20-
Color="@pb.Color" Icon="@pb.Icon" Text="@pb.Text" Size="pb.Size" ShowShadow="@pb.ShowShadow"
21-
IsDisabled="@pb.IsDisabled" IsBlock="@pb.IsBlock" IsOutline="@pb.IsOutline"
21+
Color="@pb.Color" Icon="@pb.Icon" Text="@pb.Text"
22+
IsAsync="@pb.IsAsync" IsKeepDisabled="pb.IsKeepDisabled"
23+
Size="pb.Size" ShowShadow="@pb.ShowShadow" IsDisabled="@pb.IsDisabled"
24+
IsBlock="@pb.IsBlock" IsOutline="@pb.IsOutline"
2225
OnBeforeClick="@pb.OnBeforeClick" OnClose="@pb.OnClose" OnConfirm="() => OnClickConfirm(pb)"
2326
ConfirmIcon="@pb.ConfirmIcon" ConfirmButtonColor="@pb.ConfirmButtonColor"
2427
ConfirmButtonText="@pb.ConfirmButtonText" CloseButtonColor="@pb.CloseButtonColor"

src/BootstrapBlazor/Extensions/DownloadServiceExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public static async Task DownloadFolderAsync(this DownloadService download, stri
4949
var destZipFile = $"{directoryName}.zip";
5050
ZipFile.CreateFromDirectory(folder, destZipFile);
5151

52-
using var stream = new FileStream(destZipFile, FileMode.Open);
52+
await using var stream = new FileStream(destZipFile, FileMode.Open);
5353
await download.DownloadFromStreamAsync(new DownloadOption() { FileName = downloadFileName, FileStream = stream });
5454
}
5555

test/UnitTest/Components/DownloadTest.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
// See the LICENSE file in the project root for more information.
44
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
55

6-
using Microsoft.JSInterop;
7-
86
namespace UnitTest.Components;
97

108
public class DownloadTest : BootstrapBlazorTestBase
@@ -96,6 +94,18 @@ public async Task DownloadFromStreamAsync_Null()
9694
});
9795
var btn = cut.Find("button");
9896
await Assert.ThrowsAsync<InvalidOperationException>(() => cut.InvokeAsync(() => btn.Click()));
97+
98+
var trigger = cut.FindComponent<Button>();
99+
trigger.SetParametersAndRender(pb =>
100+
{
101+
pb.Add(a => a.OnClick, async () =>
102+
{
103+
var stream = new MemoryStream();
104+
await downloadService.DownloadFromStreamAsync("", stream);
105+
});
106+
});
107+
btn = cut.Find("button");
108+
await Assert.ThrowsAsync<InvalidOperationException>(() => cut.InvokeAsync(() => btn.Click()));
99109
}
100110

101111
[Fact]
@@ -131,7 +141,7 @@ public async Task DownloadFolderAsync_Ok()
131141
{
132142
File.Delete(zipFile);
133143
}
134-
using var fs = File.Create(fileName);
144+
await using var fs = File.Create(fileName);
135145
fs.Close();
136146
btn = cut.Find("button");
137147
await cut.InvokeAsync(() => btn.Click());
@@ -175,5 +185,16 @@ public async Task DownloadFromUrlAsync_Null()
175185
});
176186
var btn = cut.Find("button");
177187
await Assert.ThrowsAsync<InvalidOperationException>(() => cut.InvokeAsync(() => btn.Click()));
188+
189+
var trigger = cut.FindComponent<Button>();
190+
trigger.SetParametersAndRender(pb =>
191+
{
192+
pb.Add(a => a.OnClick, async () =>
193+
{
194+
await downloadService.DownloadFromUrlAsync("", "./favicon.png");
195+
});
196+
});
197+
btn = cut.Find("button");
198+
await Assert.ThrowsAsync<InvalidOperationException>(() => cut.InvokeAsync(() => btn.Click()));
178199
}
179200
}

0 commit comments

Comments
 (0)