geting information from Treeview with HierarchicalDataTemplate - silverlight

Good day!
I have such a template:
<common:HierarchicalDataTemplate x:Key="my2ndPlusHierarchicalTemplate" ItemsSource="{Binding Children}">
<StackPanel Margin="0,2,5,2" Orientation="Vertical" Grid.Column="2">
<CheckBox
IsTabStop="False"
IsChecked="False"
Click="ItemCheckbox_Click"
Grid.Column="1"
/>
<TextBlock Text="{Binding Name}" FontSize="16" Foreground="#FF100101" HorizontalAlignment="Left" FontFamily="Verdana" FontWeight="Bold" />
<TextBlock Text="{Binding Description}" FontFamily="Verdana" FontSize="10" HorizontalAlignment="Left" Foreground="#FFA09A9A" FontStyle="Italic" />
<TextBox Width="100" Grid.Column="4" Height="24" LostFocus="TextBox_LostFocus" Name="tbNumber"></TextBox>
</StackPanel>
</common:HierarchicalDataTemplate>
for a Treeview
<controls:TreeView x:Name="tvServices" ItemTemplate="{StaticResource myHierarchicalTemplate}" ItemContainerStyle="{StaticResource expandedTreeViewItemStyle}" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="3" BorderBrush="#FFC1BCBC" FontFamily="Verdana" FontSize="14">
</controls:TreeView>
I want to know the Name property of each TextBox in Treeview to make validation of each textbox such as:
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
tbNumber.ClearValidationError();
if ((!tbNumber.Text.IsZakazNumberValid()) && (tbNumber.Text != ""))
{
tbNumber.SetValidation(MyStrings.NumberError);
tbNumber.RaiseValidationError();
isValid = false;
}
else
{
isValid = true;
}
}
and I wnat to see what check boxes were checked
how can I do it?

I'm not sure I'm clear why you need to know the name.
In this case the sender parameter of the LostFocus event is the TextBox in question. Hence you could use:-
TextBox tb = (TextBox)sender;
Now use this tb variable instead of using tbNumber (which doesn't actually exist because its defined in a template).

Related

WPF add button in combobox

I want to add button in combobox, which contains ItemTemplate. First, that I tried was this:
<ComboBox Name="oilWells_comboBox"
Style="{StaticResource MMComboBox}"
MaxWidth="100"
ItemsSource="{Binding DataContext.OilWellCollection, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:MainWindow}}"
Margin="0">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<CheckBox IsChecked="{Binding Path=IsDisplay}" Checked="FilterDataGrid" Unchecked="FilterDataGrid">
<CheckBox.Content>
<TextBlock MinWidth="100" Text="{Binding Path=Name}" HorizontalAlignment="Center" TextWrapping="Wrap" TextTrimming="CharacterEllipsis"/>
</CheckBox.Content>
</CheckBox>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<Button Content="Clear" Height="20" HorizontalAlignment="Stretch"></Button>
</ComboBox>
But I've got an exception, which said what i cant add items to control, which has ItemTemplate. The second one was this:
<ComboBox Name="oilWells_comboBox"
Style="{StaticResource MMComboBox}"
MaxWidth="100"
ItemsSource="{Binding DataContext.OilWellCollection, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:MainWindow}}"
Margin="0">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<CheckBox IsChecked="{Binding Path=IsDisplay}" Checked="FilterDataGrid" Unchecked="FilterDataGrid">
<CheckBox.Content>
<TextBlock MinWidth="100" Text="{Binding Path=Name}" HorizontalAlignment="Center" TextWrapping="Wrap" TextTrimming="CharacterEllipsis"/>
<Button Content="Clear" Height="20" HorizontalAlignment="Stretch"></Button>
</CheckBox.Content>
</CheckBox>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
But in this case button adds after each checkbox. Have you any ideas, how to do this only once? Thanks you in advance)
Right Click ComboBox in designer surface / or in Document Outline at the left side outside designer surface > Edit Template > Edit copy.
This will generate some Styles under Window.Resources, find ItemsPresenter and wrap it with StackPanel and Button as shown below :
<StackPanel Grid.ColumnSpan="2">
<Button Content="Additional"/>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</StackPanel>
Try this in windows loaded event and it should work.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Button b = new Button();
b.Content = "My Button";
b.Click += new RoutedEventHandler(MyBtn_Click);
oilWells_comboBox.Items.Add(b);
}

How do I set focus in side an autocomplete textbox

I have downloaded 3rd party autocomplete textbox and referenced it in my project. I have 3 autocomplete textboxes FirstName, LastName, ReceiptNo. When the form loads I want the firstname to be in focus. How to achieve this.
I have tried several steps like
//Eventhandler while form loads
private void Page_Loaded_1(object sender, RoutedEventArgs e)
{
FirstName.Focus();
}
or
//Eventhandler while autocomplete textbox loads
void FirstName_GotFocus(object sender, RoutedEventArgs e)
{
FirstName.Focus();
}
I also tried creating a bool isvisible property and binding it to autocomplete FirstName textbox in Xaml but that does not works. Any help will be appreciated.
My xaml code is given below
<wpf:AutoCompleteTextBox Style="{StaticResource AutoComp}"
Height="32"
Canvas.Left="33"
ToolTip="First Name"
Canvas.Top="120"
Width="205"
Padding="10,5"
TabIndex="1001"
VerticalAlignment="Top"
Loaded="FirstName_GotFocus"
Watermark=""
IconPlacement="Left"
IconVisibility="Visible"
Delay="100"
Text="{Binding FirstName, Mode=TwoWay, TargetNullValue=''}"
Provider="{Binding FirstNameSuggestions}">
<wpf:AutoCompleteTextBox.ItemTemplate>
<DataTemplate>
<Border Padding="5">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding}"
FontWeight="Bold" />
</StackPanel>
</Border>
</DataTemplate>
</wpf:AutoCompleteTextBox.ItemTemplate>
</wpf:AutoCompleteTextBox>
<Label Style="{StaticResource Devlbl}"
Canvas.Left="250"
Content="Last Name"
Canvas.Top="90" />
<wpf:AutoCompleteTextBox Style="{StaticResource AutoComp}"
Height="32"
ToolTip="Last Name"
Canvas.Left="250"
Canvas.Top="120"
Width="205"
Padding="10,5"
TabIndex="1002"
VerticalAlignment="Top"
Watermark=""
IconPlacement="Left"
IconVisibility="Visible"
Delay="100"
Text="{Binding LastName, Mode=TwoWay, TargetNullValue=''}"
Provider="{Binding LastNameSuggestions}">
<wpf:AutoCompleteTextBox.ItemTemplate>
<DataTemplate>
<Border Padding="5">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding}"
FontWeight="Bold" />
</StackPanel>
</Border>
</DataTemplate>
</wpf:AutoCompleteTextBox.ItemTemplate>
</wpf:AutoCompleteTextBox>
</Label>
<Label Style="{StaticResource Devlbl}"
Canvas.Left="480"
Content="Receipt No"
Canvas.Top="90" />
<!--<TextBox Canvas.Left="480"
ToolTip="Receipt No"
Canvas.Top="107"
Width="205"
MaxLength="10"
TabIndex="1003"
Style="{StaticResource CommonTextBox}"
Text="{Binding ReceiptNo,TargetNullValue=''}">
<i:Interaction.Behaviors>
<b:AllowableCharactersTextBoxBehavior RegularExpression="^[0-9]+$" MaxLength="10" />
</i:Interaction.Behaviors>
</TextBox>-->
<wpf:AutoCompleteTextBox Style="{StaticResource AutoComp}"
Height="32"
ToolTip="Receipt No"
Canvas.Left="480"
Canvas.Top="120"
Width="205"
Padding="10,5"
TabIndex="1002"
VerticalAlignment="Top"
Watermark=""
IconPlacement="Left"
IconVisibility="Visible"
Delay="100"
Text="{Binding ReceiptNo, Mode=TwoWay, TargetNullValue=''}"
e:FocusExtension.IsFocused="{Binding IsFocused, Mode=TwoWay }"
Provider="{Binding ReceiptIdSuggestions}">
<wpf:AutoCompleteTextBox.ItemTemplate>
<DataTemplate>
<Border Padding="5">
<StackPanel Orientation="Vertical" >
<TextBlock Text="{Binding}"
FontWeight="Bold">
</TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</wpf:AutoCompleteTextBox.ItemTemplate>
<i:Interaction.Behaviors>
<b:AllowableCharactersTextBoxBehavior RegularExpression="^[0-9]+$" MaxLength="15" />
</i:Interaction.Behaviors>
</wpf:AutoCompleteTextBox>
</Label>
Your first attempt is very close. Try doing the following in the Page_Loaded_1 event handler
this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
(Note - MoveFocus is a method on the Window class, it's not something you need to implement)
You should define your textboxes to have tab-indices. After the page loads, the TraversalRequest will give focus to the first tab-indexed control. If no tab indices are defined I believe it will give focus to the top of the UI hierarchy, so technically the main window would receive focus in that case.
For reference, here's an MSDN link to all of the FocusNavigationDirection options.
I changed the code as shown below and its working fine. I added a cavas as container and placed my auto complete textbox inside the canvas.
FocusNavigationDirection focusDirection = FocusNavigationDirection.Next;
// MoveFocus takes a TraveralReqest as its argument.
TraversalRequest request = new TraversalRequest(focusDirection);
UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;
if (elementWithFocus != null)
{
elementWithFocus.MoveFocus(request);
}

unable to add button controls inside the listbox dynamically in windows phone application

I am trying to add different button controls inside the listbox dynamically for each listbox item along with the data while populating it. To achieve this, under the datatemplate tag, I have added new stack panel in which I placed button controls. Now, I am trying to find the particular stackpanel in which the buttons are being placed and then make it visible true or false depending on my condition.
So, I have tried to find the desired stack panel to get the control over it through looping the listbox items. However, I am getting "Null Reference Exception" while iterating the listbox items.
The following is my xaml code and the later is my xaml.cs code:
<ListBox x:Name="TripList" Height="465" HorizontalAlignment="Left" VerticalAlignment="Top" Width="456" Background="White" Foreground="Blue">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="0,0,0,4">
<StackPanel Orientation="Vertical" Width="456">
<StackPanel Orientation="Vertical">
<StackPanel VerticalAlignment="Top" Orientation="Horizontal">
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="370" FontSize="24" Text="{Binding PUDetails}"/>
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Right" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24" Text="{Binding TripStatus}"/>
</StackPanel>
<StackPanel VerticalAlignment="Top" Orientation="Horizontal">
<StackPanel VerticalAlignment="Top" Orientation="Horizontal" Width="300">
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="Conf: "/>
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="{Binding ConfNumber}"/>
</StackPanel>
<StackPanel VerticalAlignment="Top" Orientation="Horizontal">
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Right" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="Est Do Tm: "/>
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Right" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="{Binding DOTime}"/>
</StackPanel>
</StackPanel>
<StackPanel VerticalAlignment="Top" Orientation="Vertical">
<StackPanel x:Name="stacktest" Background="Azure" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="Svc: "/>
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="{Binding TripService}"/>
</StackPanel>
<StackPanel VerticalAlignment="Top" Orientation="Horizontal">
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="PU: "/>
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="{Binding PURoute}"/>
</StackPanel>
<StackPanel VerticalAlignment="Top" Orientation="Horizontal">
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="DO: "/>
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="{Binding DORoute}"/>
</StackPanel>
<StackPanel VerticalAlignment="Top" Orientation="Horizontal">
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="Pax: "/>
<TextBlock FontWeight="Bold" Foreground="Black" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Text="{Binding PaxDetails}"/>
</StackPanel>
</StackPanel>
</StackPanel>
<StackPanel x:Name="stknotchecked" VerticalAlignment="Top" Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="300" x:Name="btnaccepttrip" Content="accept trip"></Button>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btnrejecttrip" Content="reject"></Button>
<Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btnshowmap" Content="show map"></Button>
</StackPanel>
</StackPanel>
<StackPanel x:Name="stkaccepted">
<StackPanel Orientation="Horizontal">
<Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btndirections" Content="directions"></Button>
<Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btnflightinfo" Content="flight info"></Button>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btndetails" Content="details"></Button>
<Button Background="Gray" Foreground="CadetBlue" VerticalAlignment="Top" Width="110" x:Name="btnlogtimes" Content="log times"></Button>
</StackPanel>
<StackPanel>
<Button x:Name="btnstatus" Content="set status"></Button>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
private void addbtncontrols()
{
foreach (TripsList lst in TripList.Items)
{
ListBoxItem item = TripList.ItemContainerGenerator.ContainerFromItem(lst) as ListBoxItem;
Button stk = FindFirstElementInVisualTree<Button>(item);
var stkitem =(Button)stk.FindName("btndirections");
stkitem.Visibility = Visibility.Collapsed;
}
}
private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
{
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0)
return null;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T)
{
return (T)child;
}
else
{
var result = FindFirstElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
Could someone please let me know the way to reslove my issue. Thanks in advance..
Navigating the visual tree to locate these elements and set their visibility manually is the wrong way to go about solving this problem! I see you are using databinding. Why not expose various properties of type Visibility in the model or view model you are binding to the UI, you can then bind these to the Visibility property of the various UI elements in order to show / hide them.
As an aside, learn about Styles, you XAML has numerous repeated style properties which make it lengthy and hard to follow. You should be able to define a TextBlock style that is applied to all of your TextBlocks to remove much of the repeated code in your question.
From the above description, can you provide more information about this:
Where did you invoke addbtncontrol method? If you are responding to an event, let say: Add one more item, then it should be done inside ViewModel.
"your condition": What kind of condition? Can we model it in the Listbox item ViewModel?
I have implemented something the same: Listbox with dynamic items and custom template. Also provide the ability to add new item. So, If you give me more information on what you want to accomplish or better your view model, i can help.

How to get the content of component in customized listbox

How to get the content of the hyperlink button clicked in the customized list. The code of XAML is posted below.
<ListBox Height="513" HorizontalAlignment="Left" Margin="9,88,0,0" Name="listBox1" VerticalAlignment="Top" Width="436">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<TextBlock Text="{Binding ImageSource}" Height="73" Width="73" VerticalAlignment="Top" Margin="0,10,8,0"/>
<StackPanel Width="370">
<HyperlinkButton Content="{Binding usrname}" Click="eventhandler" Foreground="#FFC8AB14" FontSize="24" />
<TextBlock Text="{Binding msg}" TextWrapping="Wrap" FontSize="20" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Thanks alot in advance
Your event handler will have a source argument which is a reference to the HyperlinkButton. You can use it as follows:
public void eventhandler(object source, EventArgs e)
{
HyperlinkButton button = source as HyperlinkButton;
var foo = button.Content;
}

WPF Xaml processing order

I have a simple address form for a customer. The country and state combo boxes are linked to ListCollectionViews. This is so when the user changes the country settings, the state list can be filtered in the model view. The problem is that when the form loads some previous information, the state combo box is blank even through it has data. It seems to be because of the order in they are placed in the xaml. If I put the country combo box before the state, if works fine, but I would like the country to come after the state. Is there a way I can leave the xaml layout the way it is, but have the country combo box processed before the state?
Xaml:
<StackPanel Orientation="Horizontal">
<TextBlock Height="23" Name="tbkMailState" Text="State/Province:" Width="80" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2" Foreground="Black" />
<ComboBox Height="23" Name="cmbMailState" Width="200" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2" Foreground="Black" ItemsSource="{Binding GeoStateListMail}" SelectedValue="{Binding OpenEntityListing.EntityMailAddress.GeoState_Id}" DisplayMemberPath="Name" SelectedValuePath="Id" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Height="23" Name="tbkMailCountry" Text="Country:" Width="80" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2" Foreground="Black" />
<ComboBox Height="23" Name="cmbMailCountry" Width="200" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2" Foreground="Black" ItemsSource="{Binding GeoCountryListMail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding OpenEntityListing.EntityMailAddress.GeoCountry_Id}" DisplayMemberPath="Name" SelectedValuePath="Id" IsSynchronizedWithCurrentItem="True" />
</StackPanel>
ViewModel filter:
public void GeoCountry_CurrentChanged(object sender, EventArgs e)
{
GeoStateList.Filter = item =>
{
GeoState vitem = item as GeoState;
if ((OpenEntityListing == null) || (vitem == null))
{
return false;
}
return vitem.GeoCountry_Id == OpenEntityListing.EntityAddress.GeoCountry_Id;
};
}
It would be bad to be dependent on the order of the xaml being processed.
Try to find a fitting event in your ViewModel when the ComboBox should be updated and bind the View to perhaps an extra property on the ViewModel.

Resources