У меня есть пользовательский контроль, который я использую в 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>
....
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding FiltersState.GroupedTenantNames, Mode=TwoWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<uiComponents:neoCombobox
LabelText="Tenant Names"
ListBoxItems="{Binding StaticLists.TenantNames, ElementName=test}"
DisplayListBoxItems ="{Binding}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ПОЛЬЗОВАТЕЛЬСКИЙ КОНТРОЛЬ ПОЛЬЗОВАТЕЛЯ
<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>
Back-end пользовательского контроллера
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;
}
}
}
}
}