Blazor中如何传递字符串引用实现原字符串同步编辑?
解决Blazor中字符串属性的双向编辑同步问题
因为C#中字符串是不可变值类型,直接传递字符串会生成副本,无法通过修改副本同步原对象的属性。针对你的场景,提供三种可行方案:
方案1:通过回调传递修改后的值(推荐,符合Blazor设计理念)
利用Blazor的EventCallback实现组件间的双向数据传递,主组件负责更新原Person对象的属性。
修改主组件代码
<div> <div @onclick="() => OpenStringEditor(nameof(Person.Name))">@user.Name</div> <div @onclick="() => OpenStringEditor(nameof(Person.Surname))">@user.Surname</div> </div> <div class="@(ShowEditor ? "ShowEditor" : "HideEditor")"> <StringEditor ToBeEdited="@_currentEditingValue" EditFinished="@HandleEditFinished" /> </div> @code { [Parameter] public Person user { get; set; } = new Person(); private bool ShowEditor; private string _currentEditingProperty; private string _currentEditingValue; private void OpenStringEditor(string propertyName) { _currentEditingProperty = propertyName; // 根据属性名获取当前值 _currentEditingValue = propertyName switch { nameof(Person.Name) => user.Name, nameof(Person.Surname) => user.Surname, _ => string.Empty }; ShowEditor = true; } private void HandleEditFinished(string newValue) { // 更新Person对应属性 switch (_currentEditingProperty) { case nameof(Person.Name): user.Name = newValue; break; case nameof(Person.Surname): user.Surname = newValue; break; } user.StoreToDB(); ShowEditor = false; } }
修改StringEditor组件
<input @bind=ToBeEdited @onfocusout="() => EditFinished.InvokeAsync(ToBeEdited)" /> @code { [Parameter] public string ToBeEdited { get; set; } = string.Empty; [Parameter] public EventCallback<string> EditFinished { get; set; } }
方案2:用包装类包裹字符串(模拟引用传递)
将字符串封装到引用类型的包装类中,传递包装类实例即可实现修改同步。
定义StringWrapper包装类
public class StringWrapper { public string Value { get; set; } = string.Empty; }
修改Person类
public class Person { public StringWrapper Name { get; set; } = new StringWrapper(); public StringWrapper Surname { get; set; } = new StringWrapper(); public void StoreToDB() { // 数据库存储逻辑 } }
修改主组件代码
<div> <div @onclick="() => OpenStringEditor(user.Name)">@user.Name.Value</div> <div @onclick="() => OpenStringEditor(user.Surname)">@user.Surname.Value</div> </div> <div class="@(ShowEditor ? "ShowEditor" : "HideEditor")"> <StringEditor WrapperToEdit="@_stringToEdit" EditFinished="@whenFinished" /> </div> @code { [Parameter] public Person user { get; set; } = new Person(); private bool ShowEditor; private StringWrapper _stringToEdit; private void OpenStringEditor(StringWrapper wrapper) { _stringToEdit = wrapper; ShowEditor = true; } private void whenFinished() { user.StoreToDB(); ShowEditor = false; } }
修改StringEditor组件
<input @bind=WrapperToEdit.Value @onfocusout="EditFinished" /> @code { [Parameter] public StringWrapper WrapperToEdit { get; set; } = new StringWrapper(); [Parameter] public EventCallback EditFinished { get; set; } }
方案3:使用表达式树动态处理属性(适合多属性场景)
通过表达式树动态获取和设置属性,避免大量switch判断,适合Person类有多个字符串属性的场景。
修改主组件代码
<div> <div @onclick="() => OpenStringEditor(() => user.Name)">@user.Name</div> <div @onclick="() => OpenStringEditor(() => user.Surname)">@user.Surname</div> </div> <div class="@(ShowEditor ? "ShowEditor" : "HideEditor")"> <StringEditor ToBeEdited="@_currentEditingValue" EditFinished="@HandleEditFinished" /> </div> @code { [Parameter] public Person user { get; set; } = new Person(); private bool ShowEditor; private Func<string> _getCurrentValue; private Action<string> _setCurrentValue; private string _currentEditingValue; private void OpenStringEditor(Expression<Func<string>> propertyExpression) { _getCurrentValue = propertyExpression.Compile(); _currentEditingValue = _getCurrentValue(); // 解析表达式生成属性赋值逻辑 var memberExpr = (MemberExpression)propertyExpression.Body; var parameter = Expression.Parameter(typeof(string)); var assignExpr = Expression.Assign(memberExpr, parameter); _setCurrentValue = Expression.Lambda<Action<string>>(assignExpr, parameter).Compile(); ShowEditor = true; } private void HandleEditFinished(string newValue) { _setCurrentValue(newValue); user.StoreToDB(); ShowEditor = false; } }
StringEditor组件同方案1
方案对比
- 方案1:最贴合Blazor单向数据流设计,逻辑清晰,维护成本低,推荐优先使用。
- 方案2:通过包装类模拟引用传递,代码改动稍大,但无需回调逻辑,适合习惯传统引用传递的场景。
- 方案3:灵活性高,适合属性较多的场景,避免重复代码,但存在轻微的表达式树编译开销(可忽略)。
内容的提问来源于stack exchange,提问作者javirs
相关产品推荐
相关产品推荐

