Blazor功能属性以返回计算值

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

Blazor Func Property to return calculated value

问题

在之前的问题的基础上,我在尝试让它工作时遇到了困难。

首先来看确实工作的部分,我在一个类上有一个属性,它会在按钮点击时发生。

public Func<Task> SelectAction { get; set; }

Razor 部分如下(这一切都是为了消除昂贵且减慢页面速度的 lambda 表达式)。

<div class="cv-selectable" @onclick="row.SelectAction">

SelectAction 设置如下:

newClaim.SelectAction = () => SwapClaimSelectedState(newClaim);

SwapClaimSelectedState 实际上会更改内部属性的值。这很有效。以下是完整的代码(问题随后提出)。

Razor 页面:

@foreach (var row in VisibleDestinations)
{
  if (row.RowType == VirtualCopyRowTypes.Claim)
  {
    <div class="cv-row cv-claim">
      <div>
        <button type="button" class="btn btn-link" @onclick="row.ExpandAction">
          <Icon Name="@row.ExpandStateIcon" height="15" />
        </button>
        <div class="cv-selectable" @onclick="row.SelectAction">
          <button type="button" class="btn btn-link">
            <Icon Name="@row.DetermineClaimsIconState" height="15" />
          </button>
          <span>@row.ClaimDisplay</span>
        </div>
      </div>
    </div>
  }
}

VisibleDestinations 中的 "row" 属性:

[JsonIgnore]
public Func<Task> SelectAction { get; set; }

[JsonIgnore]
public Func<Task> ExpandAction { get; set; }

[JsonIgnore]
public Func<Task> DetermineClaimsIconState { get; set; }

设置 VisibleDestinations 的循环:

foreach (var claim in AllPerformanceClaimsWithVisgrades)
{
  var newClaim = new VirtualCopyRow
  {
    PerformanceClaimId = claim.PerformanceClaimId,
    RowType = VirtualCopyRowTypes.Claim,
    IsVisible = true,
    ClaimDisplay = $"{claim.Issuer} {claim.Name} {claim.Version}",
  };

  newClaim.ExpandAction = () => SwapCollapsedState(newClaim);
  newClaim.SelectAction = () => SwapClaimSelectedState(newClaim);
  newClaim.DetermineClaimsIconState = () => ClaimSelectedStateIcon(newClaim);
  // ...
}

我想在 Razor 语法中调用的方法基本上会根据子对象的选择状态返回4种可能的图标状态之一。思考未选择、部分选择和全部选择:

public async Task ClaimSelectedStateIcon(VirtualCopyRow row)
{
  var result = IconNames.Blank;
  var totalChildVisgrades = Destinations
    .Count(x =>
      x.PerformanceClaimId == row.PerformanceClaimId &&
      x.RowType == VirtualCopyRowTypes.Visgrade
    );
  var totalSelectedVisgrades = Destinations
    .Count(x =>
      x.PerformanceClaimId == row.PerformanceClaimId &&
      x.RowType == VirtualCopyRowTypes.Visgrade &&
      x.IsSelected == true
    );

  if (totalChildVisgrades == 0)
    result = IconNames.Blank; // 此索赔上没有 Visgrades
  else if (totalSelectedVisgrades == 0)
    result = IconNames.UnselectAll; // 此索赔上至少有一个 Visgrade,但没有选中任何一个
  else if (totalChildVisgrades == totalSelectedVisgrades)
    result = IconNames.SelectAll; // 此索赔上至少有一个 Visgrade,且全部都选中了
  else
    result = IconNames.SomeSelected; // 此索赔上至少有两个 Visgrade,至少一个被选中但不是全部都选中了

  return result;
}

问题

我尝试了多种方式来定义 DetermineClaimsIconState 属性,其中有一个 in 和/或 TValueIconNames,但无论是在代码还是 Razor 中都会出现问题。

如果其他类型可以工作,我不需要这是一个 Func。主要要求是代码后台需要类似于以下内容:

newClaim.DetermineClaimsIconState = () => ClaimSelectedStateIcon(newClaim);

在 Razor 代码中不是 Lambda,所以它应该类似于:

<Icon Name="@row.DetermineClaimsIconState" height="15" />

更新

在尝试实现 @MrC-aka-shaun-curtis 的更新后,C# 部分是正确的,但 Razor 部分出现了以下错误。

Blazor功能属性以返回计算值

英文:

Expanding on a prior question, I am having difficulty getting it to work.

To start with the part that Does work, I have a property on a class that happens upon click of a button.

public Func&lt;Task&gt; SelectAction { get; set; }

The razor portion looks like the following (this is all in an effort to remove lambdas which are expensive and slow the page down.)

&lt;div class=&quot;cv-selectable&quot; @onclick=&quot;row.SelectAction&quot;&gt;

The SelectAction is setup like the following:

newClaim.SelectAction = () =&gt; SwapClaimSelectedState(newClaim);

The SwapClaimSelectedState essentially changes an internal properties value. This works great. Here is the full code (question to follow.)

The razor page:

@foreach (var row in VisibleDestinations)
{
  if (row.RowType == VirtualCopyRowTypes.Claim)
  {
    &lt;div class=&quot;cv-row cv-claim&quot;&gt;
      &lt;div&gt;
        &lt;button type=&quot;button&quot; class=&quot;btn btn-link&quot; @onclick=&quot;row.ExpandAction&quot;&gt;
          &lt;Icon Name=&quot;@row.ExpandStateIcon&quot; height=&quot;15&quot; /&gt;
        &lt;/button&gt;
        &lt;div class=&quot;cv-selectable&quot; @onclick=&quot;row.SelectAction&quot;&gt;
          &lt;button type=&quot;button&quot; class=&quot;btn btn-link&quot;&gt;
            &lt;Icon Name=&quot;@row.DetermineClaimsIconState&quot; height=&quot;15&quot; /&gt;
          &lt;/button&gt;
          &lt;span&gt;@row.ClaimDisplay&lt;/span&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  }
}

The VisibleDestinations "row" properties in question:

[JsonIgnore]
public Func&lt;Task&gt; SelectAction { get; set; }

[JsonIgnore]
public Func&lt;Task&gt; ExpandAction { get; set; }

[JsonIgnore]
public Func&lt;Task&gt; DetermineClaimsIconState { get; set; }

The loop to setup the VisibleDestinations:

foreach (var claim in AllPerformanceClaimsWithVisgrades)
{
  var newClaim = new VirtualCopyRow
  {
    PerformanceClaimId = claim.PerformanceClaimId,
    RowType = VirtualCopyRowTypes.Claim,
    IsVisible = true,
    ClaimDisplay = $&quot;{claim.Issuer} {claim.Name} {claim.Version}&quot;,
  };

  newClaim.ExpandAction = () =&gt; SwapCollapsedState(newClaim);
  newClaim.SelectAction = () =&gt; SwapClaimSelectedState(newClaim);
  newClaim.DetermineClaimsIconState = () =&gt; ClaimSelectedStateIcon(newClaim);
  ...
}

The method that I want to call within the razor syntax essentially returns 1 of 4 possible icon states based on child object selection states. Think none-selected, some-selected and all-selected:

public async Task ClaimSelectedStateIcon(VirtualCopyRow row)
{
  var result = IconNames.Blank;
  var totalChildVisgrades = Destinations
    .Count(x =&gt;
      x.PerformanceClaimId == row.PerformanceClaimId &amp;&amp;
      x.RowType == VirtualCopyRowTypes.Visgrade
    );
  var totalSelectedVisgrades = Destinations
    .Count(x =&gt;
      x.PerformanceClaimId == row.PerformanceClaimId &amp;&amp;
      x.RowType == VirtualCopyRowTypes.Visgrade &amp;&amp;
      x.IsSelected == true
    );

  if (totalChildVisgrades == 0)
    result = IconNames.Blank; // There are no Visgrades on this Claim
  else if (totalSelectedVisgrades == 0)
    result = IconNames.UnselectAll; // There is at least one Visgrade on the Claim and None are selected
  else if (totalChildVisgrades == totalSelectedVisgrades)
    result = IconNames.SelectAll; // There is at least one Visgrade on the Claim and they are All selected
  else
    result = IconNames.SomeSelected; // There is at least two Visgrades on the Claim and at least one but not All are selected

  return result;
}

Question

I have tried multiple permutations of how to define the DetermineClaimsIconState property where I have an in and/or TValue of IconNames and there is always some issue either in code or razor.

I do NOT need this to be a Func if some other type will work. The main requirement is that the code-behind needs to be something similar to:

newClaim.DetermineClaimsIconState = () =&gt; ClaimSelectedStateIcon(newClaim);

Where I pass the newClaim object to the ClaimSelectiedStateIcon method.

AND that the razor code is NOT a lambda so it should look similar to:

&lt;Icon Name=&quot;@row.DetermineClaimsIconState&quot; height=&quot;15&quot; /&gt;

UPDATE

After attempting to implement @MrC-aka-shaun-curtis updates, the c# is good but the razor gives the following error.

Blazor功能属性以返回计算值

答案1

得分: 1

看着你的方法 ClaimSelectedStateIcon

  1. 返回类型是 Task,但你尝试返回一个 IconValues 对象 [我假设是一个枚举?]。
  2. 我没有看到任何异步方法调用,所以我假设你正在收到关于这方面的警告。

它应该像这样:

public Task<IconNames> ClaimSelectedStateIcon(VirtualCopyRow row)
{
  var result = IconNames.Blank;

    //....

  return Task.FromResult(result);
}

而你的委托声明:

public Func<Task<IconNames>> DetermineClaimsIconState { get; set; }
英文:

Looking at your method ClaimSelectedStateIcon:

  1. The return type is Task, but you try to return an IconValues object [I assume an enum?].
  2. I see no async methods called so I assume you're getting warnings about that.

It should look like:

public  Task&lt;IconNames&gt; ClaimSelectedStateIcon(VirtualCopyRow row)
{
  var result = IconNames.Blank;

    //....

  return Task.FromResult(result);
}

And your delegate declared:

public Func&lt;Task&lt;IconNames&gt;&gt; DetermineClaimsIconState { get; set; }

答案2

得分: 0

感谢 @mrc-aka-shaun-curtis 的协助。最终产品是:

    public Func&lt;VirtualizedRow, IconNames&gt; GetBulkCopyIconState { get; set; }
    public IconNames BulkIconStateForRow
    {
      get
      {
        var result = IconNames.Blank;

        if (GetBulkCopyIconState is not null)
          result = GetBulkCopyIconState.Invoke(this);

        return result;
      }
    }

当创建不同行时,它们都设置如下:

    visgradeRow.GetBulkCopyIconState = (e) =&gt; DetermineBulkCopyIconState(visgradeRow);

进行实际计算以确定显示哪个图标:

    public IconNames DetermineBulkCopyIconState(VirtualizedRow row)
    {
      ... 魔法酱

      return result;
    }

 Razor 页面/组件上使用:

    &lt;button type=&quot;button&quot; class=&quot;btn btn-sm btn-link p-0 bulk-copy&quot; @onclick=&quot;cell.SecondaryAction&quot;&gt;
      &lt;Icon Name=&quot;@row.BulkIconStateForRow&quot; height=&quot;12&quot; class=&quot;@row.BulkIconStateForRow&quot; /&gt;
    &lt;/button&gt;
英文:

Thanks to @mrc-aka-shaun-curtis for assistance. The final product is:

public Func&lt;VirtualizedRow, IconNames&gt; GetBulkCopyIconState { get; set; }
public IconNames BulkIconStateForRow
{
  get
  {
    var result = IconNames.Blank;

    if (GetBulkCopyIconState is not null)
      result = GetBulkCopyIconState.Invoke(this);

    return result;
  }
}

When creating differet rows, they all are setup like the following:

visgradeRow.GetBulkCopyIconState = (e) =&gt; DetermineBulkCopyIconState(visgradeRow);

Do the actual calculation for determining which icon to show:

public IconNames DetermineBulkCopyIconState(VirtualizedRow row)
{
  ... Magic sauce

  return result;
}

Using it on the razor page/component:

&lt;button type=&quot;button&quot; class=&quot;btn btn-sm btn-link p-0 bulk-copy&quot; @onclick=&quot;cell.SecondaryAction&quot;&gt;
  &lt;Icon Name=&quot;@row.BulkIconStateForRow&quot; height=&quot;12&quot; class=&quot;@row.BulkIconStateForRow&quot; /&gt;
&lt;/button&gt;

huangapple
  • 本文由 发表于 2023年5月24日 22:40:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76324730.html
匿名

发表评论

匿名网友

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

确定