gpt4 book ai didi

c# - 如何与 Mode=OneWay 绑定(bind)并仅在保存时传播更改?

转载 作者:行者123 更新时间:2023-12-02 04:08:19 25 4
gpt4 key购买 nike

问题

如何才能使对注释的更改仅在单击“保存”按钮而不是“失去焦点”时传播回列表?

只有当注释发生更改时,才应启用保存按钮。

用户界面

示例应用程序如下所示:

UI

当前的行为是:

  • 单击注释会将其文本放入 TextBox 中;没关系。
  • TextBox 失去焦点时,TextBox 中更改的文本将写回到列表中(默认绑定(bind)行为);但我只希望在单击保存按钮时发生这种情况。
  • Save 按钮始终处于激活状态,因为 CanExecute(object parameter) 尚未正确实现;仅当 TextBox 文本与所选注释的文本不同时才激活它。

到目前为止我的研究

  • 选项 1:一些 Internet 来源表示将不同的属性绑定(bind)到 TextBox 并以编程方式检查它是否与 ListView< 的 SelectedItem 不同。我希望有一种方法,除了已经存在的 ListOfNotesSelectedNote 之外,无需引入第三个属性。
  • 选项 2:某些 Internet 来源建议配置 Mode=OneWay,以便单击 ListView 中的项目更新 TextBox,但不另一种方式。这听起来像是我更喜欢的解决方案,但我无法从代码示例中弄清楚如何以编程方式引发事件,以便将 TextBox 中的更改写回 单击保存按钮时的ListView

我发现了其他与我的类似的 Stackoverflow 问题,但这些问题的答案并没有帮助我解决问题:

代码

此示例当前在焦点丢失时进行双向绑定(bind)。我需要如何更改它才能获得上述行为?

https://github.com/lernkurve/WpfBindingOneWayWithSaveButton

MainWindow.xaml

<Window x:Class="WpfBindingOneWayWithSaveButton.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpfBindingOneWayWithSaveButton="clr-namespace:WpfBindingOneWayWithSaveButton"
mc:Ignorable="d"
Title="MainWindow" Height="188.636" Width="299.242">
<Window.DataContext>
<wpfBindingOneWayWithSaveButton:MainWindowsViewModel />
</Window.DataContext>
<Grid>
<GroupBox Header="List of notes" HorizontalAlignment="Left" VerticalAlignment="Top" Height="112" Width="129" Margin="0,24,0,0">
<ListView ItemsSource="{Binding ListOfNotes}" SelectedItem="{Binding SelectedNote}" DisplayMemberPath="Text" HorizontalAlignment="Left" Height="79" VerticalAlignment="Top" Width="119" Margin="0,10,-2,0"/>
</GroupBox>
<GroupBox Header="Change selected note" HorizontalAlignment="Left" Margin="134,24,0,0" VerticalAlignment="Top" Height="112" Width="151">
<Grid HorizontalAlignment="Left" Height="89" Margin="0,0,-2,0" VerticalAlignment="Top" Width="141">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40*"/>
<ColumnDefinition Width="101*"/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding SelectedNote.Text}" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="121" Margin="10,7,0,0" Grid.ColumnSpan="2"/>
<Button Command="{Binding SaveCommand}" Content="Save" HorizontalAlignment="Left" VerticalAlignment="Top" Width="121" Margin="10,35,0,0" Grid.ColumnSpan="2"/>
</Grid>
</GroupBox>
</Grid>
</Window>

MainWindowsViewModel.cs

using System.Collections.ObjectModel;
using System.Windows.Input;

namespace WpfBindingOneWayWithSaveButton
{
public class MainWindowsViewModel
{
public ObservableCollection<Note> ListOfNotes { get; set; }

public Note SelectedNote { get; set; }

public ICommand SaveCommand { get; set; }

public MainWindowsViewModel()
{
ListOfNotes = new ObservableCollection<Note>
{
new Note { Text = "Note 1" },
new Note { Text = "Note 2" }
};
SaveCommand = new SaveCommand(this);
}
}
}

SaveCommand.cs

using System;
using System.Windows.Input;

namespace WpfBindingOneWayWithSaveButton
{
public class SaveCommand : ICommand
{
private MainWindowsViewModel vm;

public SaveCommand(MainWindowsViewModel vm)
{
this.vm = vm;
}

public bool CanExecute(object parameter)
{
// What should go here?
return true;

// Pseudo code
// return (is the TextBox text different from the original note text)
}

public void Execute(object parameter)
{
// What should go here?

// Pseudo code
// Let WPF know that the TextBox text has changed
// Invoke the binding so it propagates the TextBox text back to the list
}

public event EventHandler CanExecuteChanged;
}
}

Note.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfBindingOneWayWithSaveButton
{
public class Note : INotifyPropertyChanged
{
private string text;

public string Text
{
get { return text; }
set
{
text = value;
OnPropertyChanged();
}
}

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

最佳答案

将文本绑定(bind)到 SaveButtonCommandParameter,以便将其传递到 Save 方法进行更新。

 <TextBox x:Name="NoteTextBox" Text="{Binding SelectedNote.Text, Mode=OneTime}" ../>
<Button Command="{Binding SaveCommand}"
CommandParameter="{Binding ElementName=NoteTextBox, Path=Text}",
Content="Save" />

public bool CanExecute(object parameter)
{
return vm.SelectedNote.Text != parameter as string;
}

public void Execute(object parameter)
{
vm.SelectedNote.Text = parameter as string;
}

关于c# - 如何与 Mode=OneWay 绑定(bind)并仅在保存时传播更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38253766/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com