我有textbox
<TextBox Text="{Binding DisplayNickName}"
Style="{StaticResource enternickname}"
Margin="10,10,0,0"/>
他的风格中有一个按钮。我希望当我单击用户的昵称时,在文件和模型中更新用户的昵称,但我不知道该怎么做。尝试解决我添加到Model
方法中的问题
public void update_nick(string nickname)
{
// обновляем в файле
JsonData.set_name(nickname);
// устанавливаем ник в model
this.nickname = nickname;
}
之后我想在虚拟机中发出命令,但不幸的是我不知道传入数据到底要采取什么(联系什么来获取它)并且我现在陷入了这一点,所以我希望更有经验的人提供帮助,我到底应该在VM中联系什么才能将数据输入到文本框中(我的想法是DisplayNickName)以及如何在样式中指定命令?一种风格
<!--Добавим текст бокс-->
<TextBox
Text="{TemplateBinding Text}"
Background="Transparent"
BorderThickness="0"
Foreground="#deddd0"
FontSize="20"
Margin="1,0,0,0"
x:Name="NameBox"
MaxLength="15"
Width="auto"/>
<!--Кнопка подтвеждения никнейма-->
<Button VerticalAlignment="Center"
HorizontalAlignment="Right"
Background="Transparent"
BorderThickness="0"
Cursor="Hand"
Command="{Binding DataContext.UpdateNicknameCommand, RelativeSource={RelativeSource AncestorType=Window}}"
CommandParameter="{Binding Text, ElementName=NameBox}">
<Image Source="/images/check_mark.png" Width="25" Height="25"/>
<!--Добавил в стиль кнопки триггеры для того чтобы она выводилась только при вводе и чтобы фон не менялся-->
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsKeyboardFocused, ElementName=NameBox}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" TargetName="Border" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
更改昵称的命令及命令方法
public ICommand ChangeNickNameCommand { get; set; }
private void ChangeNickName(object obj)
{
if (obj is string nickname)
{
_accountModel.update_nick(nickname);
}
}
来自带有绑定的构造函数的一段代码
// привязываем команду
ChangeNickNameCommand = new RelayCommand(ChangeNickName);
I命令码
class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Func<object, bool> _canExecute;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);
public void Execute(object parameter) => _execute(parameter);
}
让我解释一下我在评论中所说的话。
现在,您拥有了一种“样式”,它不包含一个特定控件的类型,而是包含一组不同控件的一种大杂烩。这种方法不方便、缺乏支持且难以管理。首先,你需要解决这个问题。嗯,在帮助下就可以简单地解决
UserControl
。简单的例子
右键单击项目中的项目/文件夹,然后选择“添加”>“用户控制”>指定名称>“添加”。我个人只会称呼它
TestControl
。工作室将为我们生成2个文件,
XAML
并且CS
(一切都像窗口一样)。打开
.cs
并添加 2 个包含必要数据的属性。在我们的例子中,这是一个需要命令的按钮,我们还以显示标题为例。实际上,我们
propdp
在构造函数之后编写并单击TAB
,工作室会亲切地为我们创建代码,调整它以适合我们自己,设置必要的类型和名称。结果,我们得到这样的结果:接下来,打开它
XAML
并在其中写入所需的设计。这里有一个关于绑定的重要点:控件没有DataContext
,所有绑定通常都是通过名称或类似的机制进行的,所以一开始我们会设置控件x:Name
(我通常简单地写uc
)。结果,我们得到以下标记:CommandParameter
,根据您的想法(据我了解),您希望TextBox
使用类似的绑定将输入的文本传递给命令(同样,我们按名称查找所需的控件并获取其属性),我们将单击按钮时将输入的文本传递给命令。您现在就可以使用它。打开一个窗口并在那里写入
<namespace:ИмяКонтрола Свойства = "Значения" />
,在我的例子中它将如下所示:<local:TestControl Title="Супер контрол с кнопкой"/>
工作室会一直抱怨,直到我们成功组装该项目,这就是我们实际所做的,重建它并启动它。在屏幕上我们会看到这样的东西
恭喜您获得第一个用户控件。有了它,你现在可以启动 MVVM...
MVVM、数据传输、绑定
实际上,我们现在的任务是通过单击按钮将输入的数据接收到虚拟机中,然后将其发送到模型,而模型又必须在那里执行某些操作。
我们编写
Model
,让它成为一个简单的类,它将把输入的行添加到文件中。我会尽可能简化,但我想你会理解本质......现在我们编写ViewModel,它的任务很简单,使用命令从按钮获取文本并将其发送到模型。让它是这样的:
RelayCommand
,这是什么partial
等等ObservableObject
?我很懒(我建议你这样做),我将这些ICommand
等的所有实现都交给了INotifyPropertChanged
“代码生成器”。如果你有兴趣,就研究一下CommunityToolkit.Mvvm
,如果没有,就手动写一下;网上有很多这方面的例子。剩下的就是将命令绑定到窗口
XAML
并将其设置到DataContext
窗口。我们在 XAML 中编写一个绑定到我们的控件的命令,然后我们得到<local:TestControl Title="Супер контрол с кнопкой" Command="{Binding SendCommand}"/>
.好吧,我们将窗口设置DataContext
为MainViewModel
(我将其写在构造函数中DataContext = new MainViewModel();
,但你不应该这样做)。让我们启动并尝试一下。单击时,将创建一个文件,并向其中添加一个新行,该行写入用户控件文本字段中。
这实际上是一个最简单、基本的项目示例,根据 MVVM 规则,具有绑定,甚至具有自己的控制。