C# 如何防止在值更改时调用构造函数
我在DataTemplate中使用了一个自定义usercontrol。在这个用户控件中,我有一个文本框。以前,当我实现这个usercontrol时,我不会有任何问题,但现在我将它放入了一个Datatemplate中,似乎出了什么问题 每次我在文本框中键入内容时,代码都会正常运行,但在触发器结束时,会再次调用usercontrols构造函数并清除文本框。(隐藏线程调用它,因此我甚至不知道从何处开始查找此非直观调用的来源) 我正在试图找出是什么导致这个构造函数再次启动。其他绑定似乎工作正常,正在填充和显示正确的信息。只是在所有内容解析并清除ui控件的内部变量后再次调用该构造函数 当前执行: 我在文本框中输入。触发器获取文本框的“我的值”相应地过滤列表,然后调用构造函数,文本框重置为默认值“” 预期执行: 我在文本框中输入。触发器获取文本框的“我的值”,并相应地过滤列表C# 如何防止在值更改时调用构造函数,c#,wpf,constructor,user-controls,C#,Wpf,Constructor,User Controls,我在DataTemplate中使用了一个自定义usercontrol。在这个用户控件中,我有一个文本框。以前,当我实现这个usercontrol时,我不会有任何问题,但现在我将它放入了一个Datatemplate中,似乎出了什么问题 每次我在文本框中键入内容时,代码都会正常运行,但在触发器结束时,会再次调用usercontrols构造函数并清除文本框。(隐藏线程调用它,因此我甚至不知道从何处开始查找此非直观调用的来源) 我正在试图找出是什么导致这个构造函数再次启动。其他绑定似乎工作正常,正在填充
<UserControl x:Class="Analytics_Module.Views.TenantProfileFilterFieldsView"
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:Analytics_Module.Views"
xmlns:vm="clr-namespace:Analytics_Module.ViewModels"
xmlns:uiComponents="clr-namespace:Analytics_Module.UI_Components"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<DockPanel>
<DockPanel.DataContext>
<vm:TenantProfileFilterFieldsViewModel x:Name="test"/>
</DockPanel.DataContext>
自定义用户控件
<UserControl x:Class="Analytics_Module.UI_Components.neoCombobox"
x:Name="parent"
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:model="clr-namespace:Analytics_Module.Models"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel DataContext="{Binding ElementName=parent}" Width="200">
<Label Name="ComboboxLabel"
Content="{Binding Path=LabelText, FallbackValue='Error'}" Margin="5"/>
<TextBox Name="InputField"
Text="{Binding Path=TextBoxValue, Mode=TwoWay, FallbackValue='Error', UpdateSourceTrigger='PropertyChanged'}"/>
<!--TODO rename -->
<ListBox Name="Something"
ItemsSource="{Binding Path=DisplayListBoxItems, FallbackValue={}, Mode=TwoWay}" >
<ListBox.ItemTemplate >
<DataTemplate >
<StackPanel>
<CheckBox Margin="-1"
Content="{Binding Name, FallbackValue='Error'}"
IsChecked="{Binding Check_Status, Mode=TwoWay, FallbackValue=true}">
</CheckBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</UserControl>
用户控件后端
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Analytics_Module.Models;
using Analytics_Module.Utillity;
using System.Timers;
using System.Collections.Specialized;
namespace Analytics_Module.UI_Components
{
/// <summary>
/// Interaction logic for neoCombobox.xaml
/// </summary>
public partial class neoCombobox : UserControl
{
#region LabelText DP
public String LabelText
{
get { return (String)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
public static readonly DependencyProperty LabelTextProperty =
DependencyProperty.Register("LabelText",
typeof(string),
typeof(neoCombobox), new PropertyMetadata("")
);
#endregion
#region TextBoxValue DP
/// <summary>
/// Gets or sets the Value which is being displayed
/// </summary>
public String TextBoxValue
{
get { return (String)GetValue(TextBoxValueProperty); }
set { SetValue(TextBoxValueProperty, value); }
}
/// <summary>
/// Identified the TextBoxValue dependency property
/// </summary>
public static readonly DependencyProperty TextBoxValueProperty =
DependencyProperty.Register("TextBoxValue",
typeof(String),
typeof(neoCombobox),
new PropertyMetadata("")
);
#endregion
#region ListBoxItems DP
public ItemsChangeObservableCollection<MultiSelectDropDownListEntry> ListBoxItems
{
get { return (ItemsChangeObservableCollection<MultiSelectDropDownListEntry>)GetValue(ListBoxItemsProperty); }
set { SetValue(ListBoxItemsProperty, value); }
}
public static readonly DependencyProperty ListBoxItemsProperty =
DependencyProperty.Register("ListBoxItems",
typeof(ItemsChangeObservableCollection<MultiSelectDropDownListEntry>),
typeof(neoCombobox),
new PropertyMetadata(new ItemsChangeObservableCollection<MultiSelectDropDownListEntry>())
);
#endregion
#region DisplayListBoxItems DP
public ItemsChangeObservableCollection<MultiSelectDropDownListEntry> DisplayListBoxItems
{
get {
if (GetValue(DisplayListBoxItemsProperty) == null)
{
SetValue(DisplayListBoxItemsProperty, new ItemsChangeObservableCollection<MultiSelectDropDownListEntry>());
}
return (ItemsChangeObservableCollection<MultiSelectDropDownListEntry>)GetValue(DisplayListBoxItemsProperty);
}
set { SetValue(DisplayListBoxItemsProperty, value); }
}
public static readonly DependencyProperty DisplayListBoxItemsProperty =
DependencyProperty.Register("DisplayListBoxItems",
typeof(ItemsChangeObservableCollection<MultiSelectDropDownListEntry>),
typeof(neoCombobox),
new PropertyMetadata(new ItemsChangeObservableCollection<MultiSelectDropDownListEntry>())
);
#endregion
/// <summary>
/// _timer is used to determine if a user has stopped typing.
/// The timer is started when a user starts typing again or
/// types for the first time.
/// </summary>
private readonly Timer _timerKeyPress;
/// <summary>
/// _timer is used to determine if a user has left the typing.
/// The timer is started when a user starts typing again or
/// types for the first time.
/// </summary>
private readonly Timer _timerMouseLeave;
public neoCombobox()
{
if (TextBoxValue != "") return;
InitializeComponent();
_timerKeyPress = new Timer();
_timerKeyPress.Interval = 750;
_timerKeyPress.Elapsed += new ElapsedEventHandler(UserPausedTyping);
_timerKeyPress.AutoReset = false;
_timerMouseLeave = new Timer();
_timerMouseLeave.Interval = 550;
//_timerMouseLeave.Elapsed += new ElapsedEventHandler(UserLeft);
_timerMouseLeave.AutoReset = false;
}
//TODO Add property to determine if user preferes Mouse Leave of focus leave.
protected override void OnPreviewGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
Console.WriteLine("@@@@@@@@@@@@@@@OnPreviewGotKeyboardFocus");
_timerMouseLeave.Stop();
base.OnPreviewGotKeyboardFocus(e);
}
protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
Console.WriteLine("------------OnPreviewLostKeyboardFocus");
_timerMouseLeave.Stop();
_timerMouseLeave.Start();
base.OnPreviewLostKeyboardFocus(e);
}
protected override void OnMouseEnter(MouseEventArgs e)
{
_timerMouseLeave.Stop();
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(MouseEventArgs e)
{
_timerMouseLeave.Stop();
_timerMouseLeave.Start();
base.OnMouseLeave(e);
}
protected override void OnKeyUp(KeyEventArgs e)
{
_timerKeyPress.Stop();
_timerKeyPress.Start();
}
private void UserPausedTyping(object source, ElapsedEventArgs e)
{
this.Dispatcher.Invoke(() =>
{
Console.WriteLine("@@@@@@@@@@@@@@@UserPausedTyping");
this.RefreshDisplayList();
});
}
private void UserLeft(object source, ElapsedEventArgs e)
{
this.Dispatcher.Invoke(() =>
{
Console.WriteLine("@@@@@@@@@@@@@@@User Left");
this.TextBoxValue = "";
this.RefreshDisplayList();
});
}
protected void RefreshDisplayList()
{
int ItemsourceCount = 0;
foreach (MultiSelectDropDownListEntry entry in this.DisplayListBoxItems.ToList())
{
if (!entry.Check_Status) this.DisplayListBoxItems.Remove(entry);
}
if (this.TextBoxValue == "") return;
foreach (MultiSelectDropDownListEntry entry in this.ListBoxItems)
{
if (entry.Name.ToString().ToLower().Contains(this.TextBoxValue.ToLower()) && !this.DisplayListBoxItems.Contains(entry))
{
this.DisplayListBoxItems.Add(entry);
if (ItemsourceCount++ > 15) break;
}
}
}
}
}
使用系统;
使用System.Linq;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
使用分析模块。模型;
使用Analytics_Module.Utillity;
使用系统计时器;
使用System.Collections.Specialized;
命名空间分析\u模块.UI\u组件
{
///
///neoCombobox.xaml的交互逻辑
///
公共部分类neoCombobox:UserControl
{
#区域标签文本DP
公共字符串标签文本
{
获取{return(String)GetValue(LabelTextProperty);}
set{SetValue(LabelTextProperty,value);}
}
公共静态只读DependencyProperty LabelTextProperty=
DependencyProperty.Register(“LabelText”,
类型(字符串),
typeof(neoCombobox),新属性元数据(“”)
);
#端区
#区域文本框值DP
///
///获取或设置正在显示的值
///
公共字符串TextBoxValue
{
获取{return(String)GetValue(TextBoxValueProperty);}
set{SetValue(TextBoxValueProperty,value);}
}
///
///已标识TextBoxValue依赖项属性
///
公共静态只读DependencyProperty TextBoxValueProperty=
DependencyProperty.Register(“TextBoxValue”,
类型(字符串),
类型(新组合框),
新属性元数据(“”)
);
#端区
#区域列表框项目DP
公共项目更改可观察到的收集列表框项目
{
获取{return(ItemsChangeObservableCollection)GetValue(ListBoxItemsProperty);}
set{SetValue(ListBoxItemsProperty,value);}
}
公共静态只读从属属性ListBoxItemsProperty=
DependencyProperty.Register(“ListBoxItems”,
类型(ItemsChangeObservableCollection),
类型(新组合框),
新的PropertyMetadata(新的ItemsChangeObservableCollection())
);
#端区
#区域显示ListBoxItems DP
公共项更改可观察到的集合显示ListBoxItems
{
得到{
if(GetValue(DisplayListBoxItemsProperty)==null)
{
SetValue(DisplayListBoxItemsProperty,new ItemsChangeObservableCollection());
}
返回(ItemsChangeObservableCollection)GetValue(DisplayListBoxItemsProperty);
}
set{SetValue(DisplayListBoxItemsProperty,value);}
}
公共静态只读从属属性DisplayListBoxItemsProperty=
DependencyProperty.Register(“DisplayListBoxItems”,
类型(ItemsChangeObservableCollection),
类型(新组合框),
新的PropertyMetadata(新的ItemsChangeObservableCollection())
);
#端区
///
///_计时器用于确定用户是否已停止键入。
///当用户再次开始键入或
///第一次输入。
///
专用只读定时器_timerKeyPress;
///
///_计时器用于确定用户是否已离开键入。
///当用户再次开始键入或
///第一次输入。
///
专用只读计时器\u Timer使用离开;
公共新组合框()
{
如果(TextBoxValue!=“”)返回;
初始化组件();
_timerKeyPress=新计时器();
_timerKeyPress.Interval=750;
_timerKeyPress.appeased+=新的ElapsedEventHandler(UserPausedTyping);
_timerKeyPress.AutoReset=false;
_timerMouseLeave=新计时器();
_timerMouseLeave.Interval=550;
//_timerMouseLeave.Appeased+=新的ElapsedEventHandler(UserLeft);
_timerMouseLeave.AutoReset=false;
}
//TODO添加属性以阻止
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Analytics_Module.Models;
using Analytics_Module.Utillity;
using System.Timers;
using System.Collections.Specialized;
namespace Analytics_Module.UI_Components
{
/// <summary>
/// Interaction logic for neoCombobox.xaml
/// </summary>
public partial class neoCombobox : UserControl
{
#region LabelText DP
public String LabelText
{
get { return (String)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
public static readonly DependencyProperty LabelTextProperty =
DependencyProperty.Register("LabelText",
typeof(string),
typeof(neoCombobox), new PropertyMetadata("")
);
#endregion
#region TextBoxValue DP
/// <summary>
/// Gets or sets the Value which is being displayed
/// </summary>
public String TextBoxValue
{
get { return (String)GetValue(TextBoxValueProperty); }
set { SetValue(TextBoxValueProperty, value); }
}
/// <summary>
/// Identified the TextBoxValue dependency property
/// </summary>
public static readonly DependencyProperty TextBoxValueProperty =
DependencyProperty.Register("TextBoxValue",
typeof(String),
typeof(neoCombobox),
new PropertyMetadata("")
);
#endregion
#region ListBoxItems DP
public ItemsChangeObservableCollection<MultiSelectDropDownListEntry> ListBoxItems
{
get { return (ItemsChangeObservableCollection<MultiSelectDropDownListEntry>)GetValue(ListBoxItemsProperty); }
set { SetValue(ListBoxItemsProperty, value); }
}
public static readonly DependencyProperty ListBoxItemsProperty =
DependencyProperty.Register("ListBoxItems",
typeof(ItemsChangeObservableCollection<MultiSelectDropDownListEntry>),
typeof(neoCombobox),
new PropertyMetadata(new ItemsChangeObservableCollection<MultiSelectDropDownListEntry>())
);
#endregion
#region DisplayListBoxItems DP
public ItemsChangeObservableCollection<MultiSelectDropDownListEntry> DisplayListBoxItems
{
get {
if (GetValue(DisplayListBoxItemsProperty) == null)
{
SetValue(DisplayListBoxItemsProperty, new ItemsChangeObservableCollection<MultiSelectDropDownListEntry>());
}
return (ItemsChangeObservableCollection<MultiSelectDropDownListEntry>)GetValue(DisplayListBoxItemsProperty);
}
set { SetValue(DisplayListBoxItemsProperty, value); }
}
public static readonly DependencyProperty DisplayListBoxItemsProperty =
DependencyProperty.Register("DisplayListBoxItems",
typeof(ItemsChangeObservableCollection<MultiSelectDropDownListEntry>),
typeof(neoCombobox),
new PropertyMetadata(new ItemsChangeObservableCollection<MultiSelectDropDownListEntry>())
);
#endregion
/// <summary>
/// _timer is used to determine if a user has stopped typing.
/// The timer is started when a user starts typing again or
/// types for the first time.
/// </summary>
private readonly Timer _timerKeyPress;
/// <summary>
/// _timer is used to determine if a user has left the typing.
/// The timer is started when a user starts typing again or
/// types for the first time.
/// </summary>
private readonly Timer _timerMouseLeave;
public neoCombobox()
{
if (TextBoxValue != "") return;
InitializeComponent();
_timerKeyPress = new Timer();
_timerKeyPress.Interval = 750;
_timerKeyPress.Elapsed += new ElapsedEventHandler(UserPausedTyping);
_timerKeyPress.AutoReset = false;
_timerMouseLeave = new Timer();
_timerMouseLeave.Interval = 550;
//_timerMouseLeave.Elapsed += new ElapsedEventHandler(UserLeft);
_timerMouseLeave.AutoReset = false;
}
//TODO Add property to determine if user preferes Mouse Leave of focus leave.
protected override void OnPreviewGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
Console.WriteLine("@@@@@@@@@@@@@@@OnPreviewGotKeyboardFocus");
_timerMouseLeave.Stop();
base.OnPreviewGotKeyboardFocus(e);
}
protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
Console.WriteLine("------------OnPreviewLostKeyboardFocus");
_timerMouseLeave.Stop();
_timerMouseLeave.Start();
base.OnPreviewLostKeyboardFocus(e);
}
protected override void OnMouseEnter(MouseEventArgs e)
{
_timerMouseLeave.Stop();
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(MouseEventArgs e)
{
_timerMouseLeave.Stop();
_timerMouseLeave.Start();
base.OnMouseLeave(e);
}
protected override void OnKeyUp(KeyEventArgs e)
{
_timerKeyPress.Stop();
_timerKeyPress.Start();
}
private void UserPausedTyping(object source, ElapsedEventArgs e)
{
this.Dispatcher.Invoke(() =>
{
Console.WriteLine("@@@@@@@@@@@@@@@UserPausedTyping");
this.RefreshDisplayList();
});
}
private void UserLeft(object source, ElapsedEventArgs e)
{
this.Dispatcher.Invoke(() =>
{
Console.WriteLine("@@@@@@@@@@@@@@@User Left");
this.TextBoxValue = "";
this.RefreshDisplayList();
});
}
protected void RefreshDisplayList()
{
int ItemsourceCount = 0;
foreach (MultiSelectDropDownListEntry entry in this.DisplayListBoxItems.ToList())
{
if (!entry.Check_Status) this.DisplayListBoxItems.Remove(entry);
}
if (this.TextBoxValue == "") return;
foreach (MultiSelectDropDownListEntry entry in this.ListBoxItems)
{
if (entry.Name.ToString().ToLower().Contains(this.TextBoxValue.ToLower()) && !this.DisplayListBoxItems.Contains(entry))
{
this.DisplayListBoxItems.Add(entry);
if (ItemsourceCount++ > 15) break;
}
}
}
}
}