ReactiveUI WPF - 获取文本框的最后一个字
ReactiveUI WPF - Getting the last word of a textbox
我知道这是一个微不足道的程序,但我正在学习 ReactiveUI,并且首先是整个 MVVN 的新手。我正在尝试从文本框中输入的全名中获取名字和姓氏,并将它们显示在单独的文本块中。
我成功了,但我的问题是,有没有一种方法可以只使用 LINQ 样式扩展来完成姓氏,或者我是否必须使用 select(GetLast)
调用另一个函数,如下所示?而且,如果有一种方法可以使用 LINQ 样式扩展来做到这一点,那么这样做更好还是使用 select(GetLast)
?
如果您想提供任何其他意见,我们将不胜感激。
预先感谢您提供的任何帮助。
MainWindowViewModel.cs
private string _fullName;
public string FullName
{
get => _fullName;
set => this.RaiseAndSetIfChanged(ref _fullName, value);
}
private readonly ObservableAsPropertyHelper<string> _firstName;
public string FirstName => _firstName.Value;
private readonly ObservableAsPropertyHelper<string> _lastName;
public string LastName => _lastName.Value;
public MainWindowViewModel()
{
_lastName = this.WhenAnyValue(x => x.FullName)
.Select(full => full?.Trim())
.DistinctUntilChanged()
.Where(full => full != null)
.Select(GetLast) //<-- Point of question
.ToProperty(this, x => x.LastName, out _lastName);
_firstName = this.WhenAnyValue(x => x.FullName)
.Select(full => full?.Trim())
.DistinctUntilChanged()
.Where(full => full != null)
.Select(full => full.Split(' ')[0])
.ToProperty(this, nameof(FirstName), out _firstName);
}
private string GetLast(string name)
{
string[] splitName = name.Split(' ');
if (splitName.Length > 2)
return splitName[splitName.Length - 1];
if (splitName.Length == 2)
return splitName[1];
return string.Empty;
}
MainWindow.xaml
<Label Content="_Full Name:"
Grid.Column="1" Grid.Row="2"
FontWeight="SemiBold"
Target="{Binding ElementName=fullNameTextBox}"/>
<TextBlock Text="First Name:"
Grid.Column="2" Grid.Row="2"
FontWeight="SemiBold"
Padding="5,5,0,5"/>
<TextBlock Text="Last Name:"
Grid.Column="3" Grid.Row="2"
FontWeight="SemiBold"
Padding="5,5,0,5"/>
<TextBox x:Name="fullNameTextBox"
Grid.Column="1" Grid.Row="3"
MinWidth="150"/>
<TextBlock x:Name="firstNameTextBlock"
Grid.Column="2" Grid.Row="3"
MinWidth="75"
Margin="5,0,0,0"/>
<TextBlock x:Name="lastNameTextBlock"
Grid.Column="3" Grid.Row="3"
MinWidth="75"
Margin="5,0,0,0"/>
MainWindow.xaml.cs
this.WhenActivated(disposableRegistration =>
{
this.OneWayBind(ViewModel,
vm => vm.FirstName,
v => v.firstNameTextBlock.Text)
.DisposeWith(disposableRegistration);
this.OneWayBind(ViewModel,
vm => vm.LastName,
v => v.lastNameTextBlock.Text)
.DisposeWith(disposableRegistration);
this.Bind(ViewModel,
vm => vm.FullName,
v => v.fullNameTextBox.Text)
.DisposeWith(disposableRegistration);
});
*更新
怎么样
_lastName = this.WhenAnyValue(x => x.FullName)
.Select(full => full?.Trim())
.DistinctUntilChanged()
.Where(full => !string.IsNullOrWhitespace(full))
.Select(x => x.Split(' ').Last())
.ToProperty(this, x => x.LastName, out _lastName);
至于 "is this better",老实说,那是你的决定。我认为这非常简单 - 它只是 linq - 但可能是您的同事不太会说 linq,并且更喜欢他们可以进行单元测试并轻松掌握的单独方法。
我知道这是一个微不足道的程序,但我正在学习 ReactiveUI,并且首先是整个 MVVN 的新手。我正在尝试从文本框中输入的全名中获取名字和姓氏,并将它们显示在单独的文本块中。
我成功了,但我的问题是,有没有一种方法可以只使用 LINQ 样式扩展来完成姓氏,或者我是否必须使用 select(GetLast)
调用另一个函数,如下所示?而且,如果有一种方法可以使用 LINQ 样式扩展来做到这一点,那么这样做更好还是使用 select(GetLast)
?
如果您想提供任何其他意见,我们将不胜感激。 预先感谢您提供的任何帮助。
MainWindowViewModel.cs
private string _fullName;
public string FullName
{
get => _fullName;
set => this.RaiseAndSetIfChanged(ref _fullName, value);
}
private readonly ObservableAsPropertyHelper<string> _firstName;
public string FirstName => _firstName.Value;
private readonly ObservableAsPropertyHelper<string> _lastName;
public string LastName => _lastName.Value;
public MainWindowViewModel()
{
_lastName = this.WhenAnyValue(x => x.FullName)
.Select(full => full?.Trim())
.DistinctUntilChanged()
.Where(full => full != null)
.Select(GetLast) //<-- Point of question
.ToProperty(this, x => x.LastName, out _lastName);
_firstName = this.WhenAnyValue(x => x.FullName)
.Select(full => full?.Trim())
.DistinctUntilChanged()
.Where(full => full != null)
.Select(full => full.Split(' ')[0])
.ToProperty(this, nameof(FirstName), out _firstName);
}
private string GetLast(string name)
{
string[] splitName = name.Split(' ');
if (splitName.Length > 2)
return splitName[splitName.Length - 1];
if (splitName.Length == 2)
return splitName[1];
return string.Empty;
}
MainWindow.xaml
<Label Content="_Full Name:"
Grid.Column="1" Grid.Row="2"
FontWeight="SemiBold"
Target="{Binding ElementName=fullNameTextBox}"/>
<TextBlock Text="First Name:"
Grid.Column="2" Grid.Row="2"
FontWeight="SemiBold"
Padding="5,5,0,5"/>
<TextBlock Text="Last Name:"
Grid.Column="3" Grid.Row="2"
FontWeight="SemiBold"
Padding="5,5,0,5"/>
<TextBox x:Name="fullNameTextBox"
Grid.Column="1" Grid.Row="3"
MinWidth="150"/>
<TextBlock x:Name="firstNameTextBlock"
Grid.Column="2" Grid.Row="3"
MinWidth="75"
Margin="5,0,0,0"/>
<TextBlock x:Name="lastNameTextBlock"
Grid.Column="3" Grid.Row="3"
MinWidth="75"
Margin="5,0,0,0"/>
MainWindow.xaml.cs
this.WhenActivated(disposableRegistration =>
{
this.OneWayBind(ViewModel,
vm => vm.FirstName,
v => v.firstNameTextBlock.Text)
.DisposeWith(disposableRegistration);
this.OneWayBind(ViewModel,
vm => vm.LastName,
v => v.lastNameTextBlock.Text)
.DisposeWith(disposableRegistration);
this.Bind(ViewModel,
vm => vm.FullName,
v => v.fullNameTextBox.Text)
.DisposeWith(disposableRegistration);
});
*更新
怎么样
_lastName = this.WhenAnyValue(x => x.FullName)
.Select(full => full?.Trim())
.DistinctUntilChanged()
.Where(full => !string.IsNullOrWhitespace(full))
.Select(x => x.Split(' ').Last())
.ToProperty(this, x => x.LastName, out _lastName);
至于 "is this better",老实说,那是你的决定。我认为这非常简单 - 它只是 linq - 但可能是您的同事不太会说 linq,并且更喜欢他们可以进行单元测试并轻松掌握的单独方法。