Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更新绑定不起作用的TextBlock_C#_Wpf_Mvvm_Data Binding_Datatemplate - Fatal编程技术网

C# 更新绑定不起作用的TextBlock

C# 更新绑定不起作用的TextBlock,c#,wpf,mvvm,data-binding,datatemplate,C#,Wpf,Mvvm,Data Binding,Datatemplate,我有一个关于数据绑定的问题! 我正在为一个包含一些(不同)节点的“节点编辑器”编写代码。 我使用从INotifyPropertyChanged派生的BaseViewModel类 有一个“base”nodevewmodel(从它派生而来),它具有一个observeCollection和其他属性,如节点的Name属性。它的实现如下所示: (在公共类节点设备模型:BaseViewModel中): 使用一个如下所示的OnPropertyChanged处理程序: (在基本视图模型中) 现在我有了一个附加的

我有一个关于数据绑定的问题! 我正在为一个包含一些(不同)节点的“节点编辑器”编写代码。 我使用从INotifyPropertyChanged派生的BaseViewModel

有一个“base”nodevewmodel(从它派生而来),它具有一个observeCollection和其他属性,如节点的Name属性。它的实现如下所示:

(在公共类节点设备模型:BaseViewModel中):

使用一个如下所示的OnPropertyChanged处理程序:

(在基本视图模型中)

现在我有了一个附加的RoomViewModel,它源自节点视图模型

我使用另一种不同的视图模型,我称之为RoomCollectionViewModel,对一些房间进行分组。 现在,当我将一个房间添加到我的roomcollection中时(通过在它们之间绘制连接),我会测试所有连接的房间是否具有相同的名称

如果集合中存在具有相同房间名称(例如“new room”)的已连接房间,我想将这两个房间的名称更改为例如“new room#1”和“new room#2”。到目前为止没有问题

每个节点控件(使用设置为ViewModel的数据模板创建)都包含一个显示节点名称的文本块(修改后的文本块)

这就是问题所在:

我使用修改后的文本块,因为我希望能够通过双击来修改节点的名称。这非常有效,只要我在代码中修改RoomViewModel的名称,这个(修改过的)文本块就不会更新

奇怪的是: 当一个集合中的两个同名房间被我的代码重命名,然后我双击可编辑文本块(在该过程中转换为文本框)时,我已经看到了修改后的文本。所以我假设我的数据绑定和代码是正确的,只是不完整:)

那么,如何强制更新我的EditableTextBlock,文本(DependencyProperty)似乎已正确更新

我希望你明白我的问题是什么!谢谢你的帮助

更新1 这是我的EditableTextBlock的XAML代码(它来自这里:)


下面是代码隐藏文件:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace NetworkUI {
/// <summary>
/// Interaction logic for EditableTextBlock.xaml
/// </summary>
public partial class EditableTextBlock : UserControl {
    #region Dependency Properties, Events
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(String), typeof(EditableTextBlock),
        new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    public static readonly DependencyProperty IsEditableProperty =
        DependencyProperty.Register("IsEditable", typeof(Boolean), typeof(EditableTextBlock), new PropertyMetadata(true));
    public static readonly DependencyProperty IsInEditModeProperty =
        DependencyProperty.Register("IsInEditMode", typeof(Boolean), typeof(EditableTextBlock), new PropertyMetadata(false));
    public static readonly DependencyProperty TextFormatProperty =
        DependencyProperty.Register("TextFormat", typeof(String), typeof(EditableTextBlock), new PropertyMetadata("{0}"));
    #endregion ///Dependency Properties, Events


    #region Variables and Properties
    /// <summary>
    /// We keep the old text when we go into editmode
    /// in case the user aborts with the escape key
    /// </summary>
    private String oldText;
    /// <summary>
    /// Text content of this EditableTextBlock
    /// </summary>
    public String Text {
        get { return (String)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    /// <summary>
    /// Is this EditableTextBlock editable or not
    /// </summary>
    public Boolean IsEditable {
        get { return (Boolean)GetValue(IsEditableProperty); }
        set { SetValue(IsEditableProperty, value); }
    }
    /// <summary>
    /// Is this EditableTextBlock currently in edit mode
    /// </summary>
    public Boolean IsInEditMode {
        get {
            if (IsEditable)
                return (Boolean)GetValue(IsInEditModeProperty);
            else
                return false;
        }
        set {
            if (IsEditable) {
                if (value)
                    oldText = Text;
                SetValue(IsInEditModeProperty, value);
            }
        }
    }
    /// <summary>
    /// The text format for the TextBlock
    /// </summary>
    public String TextFormat {
        get { return (String)GetValue(TextFormatProperty); }
        set  {
            if (value == "")
                value = "{0}";
            SetValue(TextFormatProperty, value);
        }
    }
    /// <summary>
    /// The formatted text of this EditablTextBlock
    /// </summary>
    public String FormattedText {
        get { return String.Format(TextFormat, Text); }
    }
    #endregion ///Variables and Properties


    #region Constructor
    /// <summary>
    /// Default constructor for the editable text block
    /// </summary>
    public EditableTextBlock() {
        InitializeComponent();
        Focusable = true;
        FocusVisualStyle = null;
    }
    #endregion ///Constructor


    #region Methods, Functions and Eventhandler
    /// <summary>
    /// Invoked when we enter edit mode
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Event arguments</param>
    void TextBox_Loaded(object sender, RoutedEventArgs e) {
        TextBox txt = sender as TextBox;
        /// Give the TextBox input focus
        txt.Focus();
        txt.SelectAll();
    }
    /// <summary>
    /// Invoked when we exit edit mode
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Event arguments</param>
    void TextBox_LostFocus(object sender, RoutedEventArgs e) {
        IsInEditMode = false;
    }
    /// <summary>
    /// Invoked when the user edits the annotation.
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Event arguments</param>
    void TextBox_KeyDown(object sender, KeyEventArgs e) {
        if (e.Key == Key.Enter) {
            IsInEditMode = false;
            e.Handled = true;
        }
        else if (e.Key == Key.Escape) {
            IsInEditMode = false;
            Text = oldText;
            e.Handled = true;
        }
    }
    /// <summary>
    /// Invoked when the user double-clicks on the textblock
    /// to edit the text
    /// </summary>
    /// <param name="sender">Sender (the Textblock)</param>
    /// <param name="e">Event arguments</param>
    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) {
        if (e.ClickCount == 2)
            IsInEditMode = true;
    }
    #endregion ///Methods, Functions and Eventhandler

}
使用系统;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
名称空间网络用户界面{
/// 
///EditableTextBlock.xaml的交互逻辑
/// 
公共部分类EditableTextBlock:UserControl{
#区域依赖属性、事件
公共静态只读DependencyProperty TextProperty=
DependencyProperty.Register(“文本”、typeof(字符串)、typeof(EditableTextBlock),
新的FrameworkPropertyMetadata(“,FrameworkPropertyMetadataOptions.bindstwoway默认值));
公共静态只读从属属性IsEditableProperty=
DependencyProperty.Register(“IsEditable”、typeof(布尔)、typeof(EditableTextBlock)、new PropertyMetadata(true));
公共静态只读从属属性IsInEditModeProperty=
DependencyProperty.Register(“IsInEditMode”、typeof(布尔)、typeof(EditableTextBlock)、new PropertyMetadata(false));
公共静态只读DependencyProperty TextFormatProperty=
Register(“TextFormat”、typeof(String)、typeof(EditableTextBlock)、newpropertyMetadata(“{0}”);
#endregion///依赖项属性、事件
#区域变量和属性
/// 
///进入编辑模式时,我们保留旧文本
///如果用户使用退出键中止
/// 
私有字符串oldText;
/// 
///此EditableTextBlock的文本内容
/// 
公共字符串文本{
获取{return(String)GetValue(TextProperty);}
set{SetValue(TextProperty,value);}
}
/// 
///此EditableTextBlock是否可编辑
/// 
公共布尔值可编辑{
获取{return(Boolean)GetValue(IsEditableProperty);}
set{SetValue(IsEditableProperty,value);}
}
/// 
///此EditableTextBlock当前是否处于编辑模式
/// 
公共布尔IsInEditMode{
得到{
如果(可编辑)
返回(布尔)GetValue(IsInEditModeProperty);
其他的
返回false;
}
设置{
如果(可编辑){
如果(值)
oldText=文本;
SetValue(IsInEditModeProperty,值);
}
}
}
/// 
///文本块的文本格式
/// 
公共字符串文本格式{
获取{return(String)GetValue(TextFormatProperty);}
设置{
如果(值==“”)
value=“{0}”;
SetValue(TextFormatProperty,value);
}
}
/// 
///此EditablTextBlock的格式化文本
/// 
公共字符串格式化文本{
获取{return String.Format(TextFormat,Text);}
}
#endregion///变量和属性
#区域构造函数
/// 
///可编辑文本块的默认构造函数
/// 
公共EditableTextBlock(){
初始化组件();
聚焦=真;
FocusVisualStyle=null;
}
#endregion///构造函数
#区域方法、函数和Eventhandler
/// 
///在进入编辑模式时调用
/// 
///寄件人
///事件参数
已加载无效文本框(对象发送器,路由目标e){
TextBox txt=发送者作为TextBox;
///给文本框输入焦点
txt.Focus();
txt.SelectAll();
}
/// 
///退出编辑模式时调用
/// 
///寄件人
///事件参数
无效T
protected virtual void OnPropertyChanged(string propertyName) {
    if (PropertyChanged != null) {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
<UserControl x:Class="NetworkUI.EditableTextBlock"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:NetworkUI"
         mc:Ignorable="d" 
         d:DesignHeight="60" d:DesignWidth="240" x:Name="mainControl">
<UserControl.Resources>
    <DataTemplate x:Key="EditModeTemplate">
        <TextBox KeyDown="TextBox_KeyDown" Loaded="TextBox_Loaded" LostFocus="TextBox_LostFocus"
                 Text="{Binding ElementName=mainControl, Path=Text, UpdateSourceTrigger=PropertyChanged}"
                 Margin="0" BorderThickness="1" />
    </DataTemplate>
    <DataTemplate x:Key="DisplayModeTemplate">
        <TextBlock Text="{Binding ElementName=mainControl, Path=FormattedText}" Margin="5,3,5,3" MouseDown="TextBlock_MouseDown" />
    </DataTemplate>

    <Style TargetType="{x:Type local:EditableTextBlock}">
        <Style.Triggers>
            <Trigger Property="IsInEditMode" Value="True">
                <Setter Property="ContentTemplate" Value="{StaticResource EditModeTemplate}" />
            </Trigger>
            <Trigger Property="IsInEditMode" Value="False">
                <Setter Property="ContentTemplate" Value="{StaticResource DisplayModeTemplate}" />
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace NetworkUI {
/// <summary>
/// Interaction logic for EditableTextBlock.xaml
/// </summary>
public partial class EditableTextBlock : UserControl {
    #region Dependency Properties, Events
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(String), typeof(EditableTextBlock),
        new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    public static readonly DependencyProperty IsEditableProperty =
        DependencyProperty.Register("IsEditable", typeof(Boolean), typeof(EditableTextBlock), new PropertyMetadata(true));
    public static readonly DependencyProperty IsInEditModeProperty =
        DependencyProperty.Register("IsInEditMode", typeof(Boolean), typeof(EditableTextBlock), new PropertyMetadata(false));
    public static readonly DependencyProperty TextFormatProperty =
        DependencyProperty.Register("TextFormat", typeof(String), typeof(EditableTextBlock), new PropertyMetadata("{0}"));
    #endregion ///Dependency Properties, Events


    #region Variables and Properties
    /// <summary>
    /// We keep the old text when we go into editmode
    /// in case the user aborts with the escape key
    /// </summary>
    private String oldText;
    /// <summary>
    /// Text content of this EditableTextBlock
    /// </summary>
    public String Text {
        get { return (String)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    /// <summary>
    /// Is this EditableTextBlock editable or not
    /// </summary>
    public Boolean IsEditable {
        get { return (Boolean)GetValue(IsEditableProperty); }
        set { SetValue(IsEditableProperty, value); }
    }
    /// <summary>
    /// Is this EditableTextBlock currently in edit mode
    /// </summary>
    public Boolean IsInEditMode {
        get {
            if (IsEditable)
                return (Boolean)GetValue(IsInEditModeProperty);
            else
                return false;
        }
        set {
            if (IsEditable) {
                if (value)
                    oldText = Text;
                SetValue(IsInEditModeProperty, value);
            }
        }
    }
    /// <summary>
    /// The text format for the TextBlock
    /// </summary>
    public String TextFormat {
        get { return (String)GetValue(TextFormatProperty); }
        set  {
            if (value == "")
                value = "{0}";
            SetValue(TextFormatProperty, value);
        }
    }
    /// <summary>
    /// The formatted text of this EditablTextBlock
    /// </summary>
    public String FormattedText {
        get { return String.Format(TextFormat, Text); }
    }
    #endregion ///Variables and Properties


    #region Constructor
    /// <summary>
    /// Default constructor for the editable text block
    /// </summary>
    public EditableTextBlock() {
        InitializeComponent();
        Focusable = true;
        FocusVisualStyle = null;
    }
    #endregion ///Constructor


    #region Methods, Functions and Eventhandler
    /// <summary>
    /// Invoked when we enter edit mode
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Event arguments</param>
    void TextBox_Loaded(object sender, RoutedEventArgs e) {
        TextBox txt = sender as TextBox;
        /// Give the TextBox input focus
        txt.Focus();
        txt.SelectAll();
    }
    /// <summary>
    /// Invoked when we exit edit mode
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Event arguments</param>
    void TextBox_LostFocus(object sender, RoutedEventArgs e) {
        IsInEditMode = false;
    }
    /// <summary>
    /// Invoked when the user edits the annotation.
    /// </summary>
    /// <param name="sender">Sender</param>
    /// <param name="e">Event arguments</param>
    void TextBox_KeyDown(object sender, KeyEventArgs e) {
        if (e.Key == Key.Enter) {
            IsInEditMode = false;
            e.Handled = true;
        }
        else if (e.Key == Key.Escape) {
            IsInEditMode = false;
            Text = oldText;
            e.Handled = true;
        }
    }
    /// <summary>
    /// Invoked when the user double-clicks on the textblock
    /// to edit the text
    /// </summary>
    /// <param name="sender">Sender (the Textblock)</param>
    /// <param name="e">Event arguments</param>
    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) {
        if (e.ClickCount == 2)
            IsInEditMode = true;
    }
    #endregion ///Methods, Functions and Eventhandler

}
<TextBlock Text="{Binding ElementName=mainControl, Path=FormattedText}" Margin="5,3,5,3" MouseDown="TextBlock_MouseDown" />
<TextBlock Text="{Binding ElementName=mainControl, Path=Text}" Margin="5,3,5,3" MouseDown="TextBlock_MouseDown" />