I have two textboxes inside an expander. I am validating the textbox for text value when a button is clicked. If the textbox is empty the textbox is given foucs.
What I want to achieve is for the expander to expand automatically when one of these texboxes gets focus.
I could not find any ways to do that on the internet. Is it possible to do so?
xaml :
<Grid>
<Expander Header="Textbox Expander">
<StackPanel Orientation="Vertical">
<TextBox Name="txtName" Height="30" Width="100" Background="WhiteSmoke" />
<TextBox Name="txtAge" Height="30" Width="100" Background="WhiteSmoke" />
</StackPanel>
</Expander>
<Button Name="btnDone" Content="Done" Width="50" Height="50" Click="btnDone_Click"/>
</Grid>
c# :
using System.Windows;
using System.Windows.Controls;
namespace TestExpanderFocus
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnDone_Click(object sender, RoutedEventArgs e)
{
Validation validation = new Validation();
if(validation.validate(ref txtName) && validation.validate(ref txtAge))
{
//Do Something.
}
}
}
}
EDIT : Since this validation class is in another application I cannot edit this.
//Seperate class in another application which cannot be edited
public class Validation
{
public bool validate(ref TextBox txtobj)
{
if (string.IsNullOrWhiteSpace(txtobj.Text))
{
MessageBox.Show("Please Enter Data..!");
txtobj.Focus();
return false;
}
return true;
}
}
What you wanted to achieve is actually pretty simple.
First give the Expander a name
<Expander x:Name="MyExpander" ... />
Second, in your validation, before you focus on the textbox, simply expand the Expander
MyExpander.IsExpanded = true;
...
-- EDIT to satisy the new requirement --
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnDone_Click(object sender, RoutedEventArgs e)
{
Validation validation = new Validation();
// since you know that the text will be focused when the validation fails
var result1 = validation.validate(ref txtName);
var result2 = validation.validate(ref txtAge);
MyExpander.IsExpanded = !result1 || !result2;
if(result1 && result2)
{
//Do Something.
}
}
}
But I must admit, this is not the nicest solution. There should be an easier way to just add Trigger to the Expander Style directly. (I will leave it to other people, since I don't have more time)
Related
I have a minimalist UserControl containing a single TextBlock which I prototype as follows:
<Grid>
<TextBlock x:Name="textBlockExt" x:FieldModifier="public"/>
</Grid>
public partial class TextBlockExt : UserControl
{
public TextBlockExt()
{
InitializeComponent();
DataContext = this;
}
public string Text
{
get => textBlockExt.Text;
set { textBlockExt.Text = value.ToUpper(); } // to be expanded later
}
}
I then consume the control by
<Grid>
<StackPanel>
<local:TextBlockExt FontSize="30" x:Name="txb" Text="Hello World" TextBlock.TextAlignment="Center"/>
<Button Content="To Upper" Width="100" Click="Button_Click"/>
</StackPanel>
</Grid>
And it's code behind is
public MainWindow()
{
InitializeComponent();
txb.textBlockExt.TextWrapping = TextWrapping.WrapWithOverflow;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
txb.Text = "one two three four five six seven eight";
}
I don't like the code in the MainWindow constructor above and need to know how to set the TextWrapping in the XAML.
Add a property TextWrapping to your TextBlockExt class. Use the same way you did for the Text property:
public TextWrapping TextWrapping {
get => txtBlockExt.TextWrapping;
set { txtBlockExt.TextWrapping = value: }
}
I want to have a combo box with a button that looks like this:
As I want to use this so that items can be selected and added to a ListView.
Issues:
I don't know how to get and icon in the button like shown
How do you get them to line up really well or is there a way to combine the two elements that I am unaware of?
Here's a working example.
Let's suppose your user control has two controls; a ComboBox and a Button. You want to be able to bind something from your main (parent) to the user control. Then upon selecting something and clicking the button, you want user control to notify to the parent of the event occurrence, and also pass the selected value.
The UserControl XAML:
<UserControl ...
d:DesignHeight="40" d:DesignWidth="200">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="160"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0" Margin="4" Name="ItemsComboBox"
ItemsSource="{Binding Source, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<Button Grid.Column="1" Margin="4" Content="+"
Click="Button_Click"/>
</Grid>
</UserControl>
The following binding will allow you to bind a list of data to the combo box, form the parent:
ItemsSource="{Binding Source, RelativeSource={RelativeSource AncestorType=UserControl}}"
From your MainWindow, you'll use the control like so:
<Grid>
<local:UCComboButton Grid.Row="0" Width="200" Height="40" x:Name="MyUC"
Source="{Binding Names}"/>
</Grid>
And in the UserControls code behind:
public partial class UCComboButton : UserControl
{
public UCComboButton()
{
InitializeComponent();
}
// We use this dependency property to bind a list to the combo box.
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(IEnumerable), typeof(UCComboButton), new PropertyMetadata(null));
public IEnumerable Source
{
get { return (IEnumerable)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
// This is to send the occurred event, in this case button click, to the parent, along with the selected data.
public class SelectedItemEventArgs : EventArgs
{
public string SelectedChoice { get; set; }
}
public event EventHandler<SelectedItemEventArgs> ItemHasBeenSelected;
private void Button_Click(object sender, RoutedEventArgs e)
{
var selected = ItemsComboBox.SelectedValue;
ItemHasBeenSelected?.Invoke(this, new SelectedItemEventArgs { SelectedChoice = selected.ToString() });
}
}
Now in the MainWindow.xaml.cs:
public MainWindow()
{
InitializeComponent();
// Subscribe to the item selected event
MyUC.ItemHasBeenSelected += UCButtonClicked;
Names = new List<string>
{
"A",
"B",
"C"
};
DataContext = this;
}
void UCButtonClicked(object sender, UCComboButton.SelectedItemEventArgs e)
{
var value = e.SelectedChoice;
// Do something with the value
}
Note that the above Names list is what's bound to the user control from the main window XAML.
There is a textbox in my mainwindow.xaml, when I enter the textbox, I expect the label in my usercontrol, known as View1.xaml will be update accordingly. However I realise the event is not raise at all in the user control when I type the textbox, can you tell me which part is wrong?
The event is able to raise in TextBox_TextChanged_1
my MainWindow.XAML
<Window xmlns:my="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:testapplication" x:Class="testapplication.MainWindow"
Title="MainWindow" Height="964" Width="790">
<Grid >
<Button x:Name="OpenView1" Content="Open Window 1" HorizontalAlignment="Left" Margin="33,70,0,0" VerticalAlignment="Top" Width="111" RenderTransformOrigin="0.279,1.409" Click="OpenView1_Click"/>
<Button x:Name="OpenView2" Content="Open Window 2" HorizontalAlignment="Left" Margin="33,169,0,0" VerticalAlignment="Top" Width="111" Click="OpenView2_Click"/>
<Button x:Name="OpenView3" Content="Open Window 3" HorizontalAlignment="Left" Margin="33,259,0,0" VerticalAlignment="Top" Width="111" Click="OpenView3_Click"/>
<local:View1 x:Name="ViewOne" HorizontalAlignment="Left" Margin="33,332,0,0" VerticalAlignment="Top" Height="226" Width="204" Visibility="Hidden"/>
<local:View2 x:Name="ViewTwo" HorizontalAlignment="Left" Margin="284,332,0,0" VerticalAlignment="Top" Height="226" Width="208" Visibility="Hidden"/>
<local:View3 x:Name="ViewThree" HorizontalAlignment="Left" Margin="534,332,0,0" VerticalAlignment="Top" Height="226" Width="196" Visibility="Hidden"/>
<TextBox HorizontalAlignment="Left" Height="42" Margin="326,70,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="182" FontSize="22" TextChanged="TextBox_TextChanged_1"/>
</Grid>
</Window>
my MainWindow.cs
namespace testapplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
//InitializeComponent();
}
//event handler
public event EventHandler<EventArgs> changedText;
private void OpenView1_Click(object sender, RoutedEventArgs e)
{
ViewOne.Visibility = Visibility.Visible;
}
private void OpenView2_Click(object sender, RoutedEventArgs e)
{
ViewTwo.Visibility = Visibility.Visible;
}
private void OpenView3_Click(object sender, RoutedEventArgs e)
{
ViewThree.Visibility = Visibility.Visible;
}
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
if (changedText != null)
{
changedText(this, e);
}
}
}
}
This is my UserControl, known as View1.xaml, it is included in my MainWindow.Xaml
namespace testapplication
{
/// <summary>
/// Interaction logic for View1.xaml
/// </summary>
public partial class View1 : UserControl
{
private MainWindow newWindow = new MainWindow();
public View1()
{
InitializeComponent();
newWindow.changedText += newWindow_ChangeText;
}
void newWindow_ChangeText(object sender, EventArgs e)
{
ViewOnelabel.Content = "Happy";
}
}
}
The problem is my ViewOnelabel.Content = "Happy" did not execute at all, it remain unchanged
There are a few things I would like to point out.
The equivalent of a winforms label in wpf is a TextBlock. A wpf label is actually a type of contentcontrol. Hence the content property.
In wpf there are routed events. These "bubble" up ( and tunnel down ) the visual tree. That means you can handle an event in the window from a control in a usercontrol inside it.
But mainly.
I encourage you to look into the MVVM pattern.
I've put together some code which illustrates these points.
I'd recommend just using binding and mvvm though.
My MainWindow markup:
Title="MainWindow" Height="350" Width="525"
TextBoxBase.TextChanged="Window_TextChanged"
>
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<StackPanel>
<Label Name="OutputLabel"/>
<TextBlock Text="{Binding OutputString}"/>
<local:UserControl1/>
</StackPanel>
</Grid>
Notice that it handles a textchanged event and because that's routing it will get the event from UserControl1 inside it.
Code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_TextChanged(object sender, TextChangedEventArgs e)
{
OutputLabel.Content = $"Happy {((TextBox)e.OriginalSource).Text}";
}
}
You don't do anything with the text from your textbox in your handler but I have some code there proves you could get at that from mainwindow if you wanted.
My viewmodel:
public class MainWindowViewModel : INotifyPropertyChanged
{
private string inputString;
public string InputString
{
get { return inputString; }
set
{
inputString = value;
OutputString = $"{inputString.Length} characters entered";
RaisePropertyChanged();
}
}
private string outputString;
public string OutputString
{
get { return outputString; }
set
{
outputString = value;
RaisePropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Usercontrol1 just has a textbox:
<Grid>
<TextBox Text="{Binding InputString, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
As you type in that textbox, the text is transferred to the bound property in my viewmodel. That hits the code in my setter. This in turn sets OutputString which is bound to my textblock.
Text changes in both my label and textblock as I type.
Here's a link to my sample on onedrive
https://1drv.ms/u/s!AmPvL3r385QhgpgOPNKPs-veFJ2O3g
The main problem here is that your View1 class is subscribing to an event on a new MainWindow instance, not the MainWindow instance created by your application on start.
Since your MainWindow class has a reference to your View1 class (a named member "ViewOne") you should just change it from the MainWindow class.
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
ViewOne.ViewOneLabel.Content = "Happy";
}
Get rid of the chenagedText event handler and all the code in the View1.xaml.cs... you don't need it.
Note: I am hoping that you are just playing around and learning here... there is no way I would condone building a WPF application in this way.
You could only use the event of the MainPage. I recomment you to add a Property to the UserControl. In my case I call it Text.
public string Text
{
set { ViewOneLabel.Content = value; }
}
In the MainWindow use the Property within the TextChanged Event.
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
OpenView1.Text = TextBox.Text;
}
You are creating a new instance of MainWindow in your UserControl. What you want to do is to hook up an event handler to the instance that you actually see on the screen. You can get a reference to this one using the Window.GetWindow method:
public partial class View1 : UserControl
{
public View1()
{
InitializeComponent();
Loaded += (s, e) =>
{
Window mainWindow = Window.GetWindow(this) as MainWindow;
if(mainWindow != null)
mainWindow.changedText += newWindow_ChangeText;
};
}
void newWindow_ChangeText(object sender, EventArgs e)
{
ViewOnelabel.Content = "Happy";
}
}
I am developing a windows phone application.In that i ask the user to login.
On the login page the user has to enter password.
Now what I want is that i give user a check box which when selected should show the characters of the password.
I have not seen any property on password box to show password characters.
Please suggest some way to do it.
Don't think that is possible with PasswordBox... just a thought, but you might accomplish the same result using a hidden TextBox and when the user clicks the CheckBox, you just hide the PasswordBox and show the TextBox; if he clicks again, you switch their Visibility state again, and so on...
Edit
And here it is how!
Just add a page, change the ContentPanel to a StackPanel and add this XAML code:
<PasswordBox x:Name="MyPasswordBox" Password="{Binding Text, Mode=TwoWay, ElementName=MyTextBox}"/>
<TextBox x:Name="MyTextBox" Text="{Binding Password, Mode=TwoWay, ElementName=MyPasswordBox}" Visibility="Collapsed" />
<CheckBox x:Name="ShowPasswordCharsCheckBox" Content="Show password" Checked="ShowPasswordCharsCheckBox_Checked" Unchecked="ShowPasswordCharsCheckBox_Unchecked" />
Next, on the page code, add the following:
private void ShowPasswordCharsCheckBox_Checked(object sender, RoutedEventArgs e)
{
MyPasswordBox.Visibility = System.Windows.Visibility.Collapsed;
MyTextBox.Visibility = System.Windows.Visibility.Visible;
MyTextBox.Focus();
}
private void ShowPasswordCharsCheckBox_Unchecked(object sender, RoutedEventArgs e)
{
MyPasswordBox.Visibility = System.Windows.Visibility.Visible;
MyTextBox.Visibility = System.Windows.Visibility.Collapsed;
MyPasswordBox.Focus();
}
This works fine, but with a few more work, you can do this fully MVVM'ed!
with default passwordbox it's not possible to implement the feature you want.
more information you can find here: http://social.msdn.microsoft.com/Forums/en/wpf/thread/98d0d4d4-1463-481f-b8b1-711119a6ba99
I created an MVVM example, which I'm also using in real life. Please note that PasswordBox.Password is not a Dependency Property and thus cannot be bound directly. It's designed like that for security reasons, for details see: How to bind to a PasswordBox in MVVM
If you want to do it anyway, you have to build a bridge to your view model using code behind. I'm not providing the converters, as you're probably using your own set of converters. If not, please ask google for suitable implementations.
EnterPasswordWindow.xaml
<Window x:Class="MyDemoApp.Controls.EnterPasswordWindow"
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:local="clr-namespace:MyDemoApp.Controls"
mc:Ignorable="d" d:DataContext="{d:DesignInstance local:EnterPasswordViewModel}"
WindowStartupLocation="CenterOwner" ResizeMode="NoResize" SizeToContent="WidthAndHeight"
Title="Enter Password">
<StackPanel Margin="4">
<TextBlock Margin="4">Please enter a password:</TextBlock>
<TextBox Margin="4" Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding ShowPassword, Converter={StaticResource BoolToVisibleConverter}}"/>
<PasswordBox Margin="4" Name="PasswordBox" Visibility="{Binding ShowPassword, Converter={StaticResource BoolToCollapsedConverter}}" PasswordChanged="PasswordBox_PasswordChanged"/>
<CheckBox Margin="4" IsChecked="{Binding ShowPassword}">Show password</CheckBox>
<DockPanel>
<Button Margin="4" Width="150" Height="30" IsDefault="True" IsEnabled="{Binding Password, Converter={StaticResource StringIsNotNullOrEmptyConverter}}" Click="Button_Click">OK</Button>
<Button Margin="4" Width="150" Height="30" IsCancel="True" HorizontalAlignment="Right">Cancel</Button>
</DockPanel>
</StackPanel>
</Window>
EnterPasswordWindow.xaml.cs
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace MyDemoApp.Controls
{
/// <summary>
/// Interaction logic for EnterPasswordWindow.xaml
/// </summary>
public partial class EnterPasswordWindow : Window
{
public EnterPasswordWindow()
{
InitializeComponent();
DataContext = ViewModel = new EnterPasswordViewModel();
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
}
public EnterPasswordViewModel ViewModel { get; set; }
private void Button_Click(object sender, RoutedEventArgs e)
{
DialogResult = true;
Close();
}
private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (!mSuppressPropertyChangedEvent && e.PropertyName == nameof(ViewModel.Password))
{
PasswordBox.Password = ViewModel.Password;
}
}
private bool mSuppressPropertyChangedEvent;
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
mSuppressPropertyChangedEvent = true;
ViewModel.Password = ((PasswordBox)sender).Password;
mSuppressPropertyChangedEvent = false;
}
}
}
EnterPasswordViewModel.cs
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace MyDemoApp.Controls
{
public class EnterPasswordViewModel : INotifyPropertyChanged
{
public string Password
{
get => mPassword;
set
{
if (mPassword != value)
{
mPassword = value;
NotifyPropertyChanged();
}
}
}
private string mPassword;
public bool ShowPassword
{
get => mShowPassword;
set
{
if (mShowPassword != value)
{
mShowPassword = value;
NotifyPropertyChanged();
}
}
}
private bool mShowPassword;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName]string propertyName = null)
{
if (string.IsNullOrEmpty(propertyName))
{
return;
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
You could create your own control that inherits from textbox however after each character you replace it with an *, storing the true value within a private variable on the page. Using a checkbox you can then toggle whether the value in the textbox shows the true value or the * value.
It's not an elegant solution nor is it a best practice, however I think it's still an alternative if you are willing to live with it.
In my WPF application, I have a databound TextBox and a databound ItemsControl. The contents of the ItemsControl is determined by the contents of the TextBox. I want to be able to type a value into the TextBox, press tab and enter the first item in the ItemsControl (created from the value in the TextBox). The problem I am having is that the tab action is evaluated before WPF creates the templated items in the ItemsControl. The following code demonstrates this problem:
<Window x:Class="BindingExample.Window1" x:Name="SelfControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:BindingExample" Title="Window1" Height="300" Width="400">
<Window.Resources>
<DataTemplate DataType="{x:Type loc:ChildClass}">
<TextBox Text="{Binding Value}" />
</DataTemplate>
</Window.Resources>
<StackPanel DataContext="{Binding ElementName=SelfControl}" Focusable="False">
<Label Content="Options: A, B, C" />
<TextBox Text="{Binding Object.Value}" />
<ItemsControl Margin="16,0,0,0" ItemsSource="{Binding Object.Children}" Focusable="False">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<TextBox Text="Box2" />
</StackPanel>
</Window>
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
namespace BindingExample
{
public partial class Window1
{
public static readonly DependencyProperty ObjectProperty = DependencyProperty.Register("Object", typeof(ParentClass), typeof(Window1));
public ParentClass Object
{
get { return GetValue(ObjectProperty) as ParentClass; }
set { SetValue(ObjectProperty, value); }
}
public Window1()
{
InitializeComponent();
Object = new ParentClass();
}
}
public class ParentClass : INotifyPropertyChanged
{
private string value;
public string Value
{
get { return value; }
set { this.value = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Children")); }
}
public IEnumerable<ChildClass> Children
{
get
{
switch (Value.ToUpper())
{
case "A": return new ChildClass[] { "A-1", "A-2", "A-2" };
case "B": return new ChildClass[] { "B-1", "B-2", "B-3" };
case "C": return new ChildClass[] { "C-1", "C-2", "C-2" };
default: return new ChildClass[] { "Unknown" };
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class ChildClass
{
public string Value { get; set; }
public static implicit operator ChildClass(string value) { return new ChildClass { Value = value }; }
}
}
In this code, I would like to type "A" into the first TextBox, press tab, and have the focus shift to the child TextBox with the text "A-1". Instead the focus skips to the TextBox with the text "Box2". How can I achieve the behavior I am looking for here?
Note: As Julien Poulin pointed out, it is possible to make this work by switching the UpdateSourceTrigger on the TextBox to PropertyChanged. This only works, however, if "as you type" binding is acceptable. In my case, I would also like to do the set the value and tab with one keystroke. Is there some way to force the ItemsControl to create its templated items on-demand?
Try to set the UpdateMode of the TextBox to PropertyChanged so the underlying value is set when you type a new value instead of when the TextBox loses focus:
<TextBox Text="{Binding Path=Object.Value, UpdateMode=PropertyChanged}" />
Here is an alternative solution. It's a bit of a hack, but appears to work. Since the templated objects in the ItemsControl aren't created until execution on the main thread pauses, this code catches the tab, updates the binding, and sets a timer to move the focus once the items have a chance to be created.
...
<TextBox Text="{Binding Object.Value}" KeyDown="TextBox_KeyDown" />
...
public partial class Window1
{
private DispatcherTimer timer;
...
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab && e.KeyboardDevice.Modifiers != ModifierKeys.Shift)
{
e.Handled = true;
var textbox = (TextBox)sender;
textbox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
(timer = new DispatcherTimer(
new TimeSpan(100000), // 10 ms
DispatcherPriority.Normal,
delegate
{
textbox.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
timer.Stop();
}, Dispatcher)).Start();
}
}
}
The only problem I see with this code is that the ItemsControl might take longer than 10 ms to populate, in which case Tab would jump over those items. Is there any way of detecting whether or not the creation of ItemsControl items has occurred?