RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 710739
Accepted
trydex
trydex
Asked:2020-08-26 11:43:27 +0000 UTC2020-08-26 11:43:27 +0000 UTC 2020-08-26 11:43:27 +0000 UTC

编辑选定对象的属性

  • 772

该程序能够编辑所选对象的属性。

这是通过ViewModel 上的SelectedObject属性实现的。

问题如下。如果我选择一个对象,编辑它的属性并在 current 中单击TabItem,那么属性就会更新。但是,如果我编辑属性并且没有从文本字段中移除光标,而是切换到另一个选项卡,则不会保存属性中的更改。

安装UpdateSourceTrigger=PropertyChanged对我不起作用。正好需要LostFocus。

如何解决?


我画了一个反映问题的例子。

在此处输入图像描述

代码隐藏:

public class PersonVm : BaseVm
{
    private string _name;
    private string _lastname;

    public string Name
    {
        get => _name;
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    public string Lastname
    {
        get => _lastname;
        set
        {
            _lastname = value;
            OnPropertyChanged();
        }
    }
}


public class MainVm : BaseVm
{
    private PersonVm _selectedPerson;

    public MainVm()
    {
        Class1.Add(new PersonVm { Name = "Алексей", Lastname = "Алексеев" });
        Class1.Add(new PersonVm { Name = "Иван", Lastname = "Иванов" });

        Class2.Add(new PersonVm { Name = "Петр ", Lastname = "Петров" });
        Class2.Add(new PersonVm { Name = "Николай", Lastname = "Николаев" });
    }
    public ObservableCollection<PersonVm> Class1 { get; } = new ObservableCollection<PersonVm>();
    public ObservableCollection<PersonVm> Class2 { get; } = new ObservableCollection<PersonVm>();

    public PersonVm SelectedPerson
    {
        get => _selectedPerson;
        set
        {
            _selectedPerson = value; 
            OnPropertyChanged();
        }
    }
}

XAML:

<Window.Resources>
    <DataTemplate x:Key="DataTemplate">
        <ListBox ItemsSource="{Binding}"
                 SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.SelectedPerson}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}" />
                        <TextBlock Text="{Binding Lastname}" 
                                   Margin="5,0,0,0"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
            </ListBox>
    </DataTemplate>
</Window.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <TabControl>
        <TabItem Header="Class1" 
                 Content="{Binding Class1}"
                 ContentTemplate="{StaticResource DataTemplate}" />

        <TabItem Header="Class2" 
                 Content="{Binding Class2}"
                 ContentTemplate="{StaticResource DataTemplate}" />
    </TabControl>

    <StackPanel Grid.Column="1">
        <TextBlock Text="Имя" />
        <TextBox Text="{Binding SelectedPerson.Name}" />
        <TextBlock Text="Фамилия" />
        <TextBox Text="{Binding SelectedPerson.Lastname}" />
    </StackPanel>
</Grid>
c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Андрей NOP
    2020-08-28T16:38:24Z2020-08-28T16:38:24Z

    目前,事实证明,当事件发生时,LostFocus绑定不再存在,因此它不会触发。在所有PreviewXXX事件中,它TextBox只有PreviewLostKeyboardFocus,如果您订阅它并使用调试器查看其中的内容Text,那么我们将看到它仍然具有绑定,因此该事件将适合我们。

    实际上,让我们尝试在订阅者中强制进行绑定更新,将以下代码添加到处理程序中:

    (sender as TextBox).GetBindingExpression(TextBox.TextProperty).UpdateSource();
    

    你会看到一切都如你所愿。

    可以做些什么呢?例如,您可以为所有必要的 添加事件处理程序TextBox,或实现TextBox具有此类行为的后继者,或者最后, make Attached Behavior。

    我认为第一个选项不好,因为。有必要在我们需要TextBox此类行为的所有窗口/控件中添加此类处理程序,如果TextBox我们中的某些人突然需要此事件的另一个处理程序,我们将不得不将其从代码中挂起。

    因此,我将展示最后两个选项。

    继承人TextBox,一切都非常简单,我创建了这个类:

    public class MyTextBox : TextBox
    {
        protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            base.OnPreviewLostKeyboardFocus(e);
            GetBindingExpression(TextProperty).UpdateSource();
        }
    }
    

    一切。TextBox这已经有效,使用它来代替标准就足够了local:MyTextBox。但是这种方法有一个缺点 - 如果您为标准样式设置样式TextBox,那么这些自定义样式将不会定期选择样式,它们必须单独设置样式,尽管实际上我们有相同的样式TextBox。

    因此,最优化的解决方案似乎是做出附加行为。

    将程序集连接到项目System.Windows.Interactivity并创建一个类:

    class TextBoxLostFocusUpdateBindingBehavior : Behavior<TextBox>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.PreviewLostKeyboardFocus += OnPreviewLostKeyboardFocus;
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.PreviewLostKeyboardFocus -= OnPreviewLostKeyboardFocus;
        }
    
        private void OnPreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            AssociatedObject.GetBindingExpression(TextBox.TextProperty).UpdateSource();
        }
    }
    

    现在在 XAML 中,添加命名空间:xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

    在正确的地方TextBox指定这种行为:

    <TextBox Text="{Binding SelectedPerson.Lastname}">
        <i:Interaction.Behaviors>
            <local:TextBoxLostFocusUpdateBindingBehavior/>
        </i:Interaction.Behaviors>
    </TextBox>
    

    PS.:值得注意的是,如果自上次更新以来没有任何更改,该技术足够智能,不会更新相同的绑定Binding。WPF因此,我们不需要采取任何额外的措施来禁用更新绑定LostFocus,它永远不会在那里更新,更新现在总是发生在PreviewLostKeyboardFocus

    • 7

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5