Dynamically update a data bound listbox C# WPF - c#

So despite finding articles online I still cannot figure this out.
I have a Listbox
<ListBox HorizontalAlignment="Left" Margin="54,35,0,0" Name="resultsbox" VerticalAlignment="Top" Width="382" Visibility="Collapsed">
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding nameElement}"/>
</StackPanel>
</DataTemplate>
</ListBox>
That is databound to
ObservableCollection<string> results = new ObservableCollection<string>();
and is updated with
private void searchbox_TextChanged(object sender, TextChangedEventArgs e)
{
resultsbox.Visibility = Visibility.Visible;
resultsbox.ItemsSource = results;
if (results.Count == 0)
{
foreach (ele item in eles)
{
if (!results.Contains(item.nameElement))
{
results.Add(item.nameElement);
}
}
}
else
{
resultsbox.Items.Clear();
}
if (searchbox.Text.Equals(""))
{
window1.Height = 47;
resultsbox.Visibility = Visibility.Collapsed;
}
if (resultsbox.Items.Count == 0)
{
resultsbox.Visibility = Visibility.Collapsed;
window1.Height = 47;
}
else{
window1.Height = 47 + (22 * resultsbox.Items.Count);
}
}
It loads ALL the data in there but WILL NOT UPDATE!
If I do resultsbox.clear() it says you can't clear bound items. If you try and clear the source it does nothing. If you try and set the resultsbox itemsource to null and clear the source then rebind it, nothing. If you try and bind the listbox to an empty source it does nothing....

The answer was changing the foreach loop in the update from
resultsbox.ItemsSource = results;
if (results.Count == 0)
{
foreach (ele item in eles)
{
if (!results.Contains(item.nameElement))
{
results.Add(item.nameElement);
}
}
}
to
results.Clear();
foreach (ele item in eles)
{
if (item.nameElement.ToLower().Contains(searchbox.Text.ToLower()))
{
results.Add(item.nameElement);
}
}
resultsbox.ItemsSource = results;

You can try using Two-Way Mode Binding to achieve your requirement IMO,
<ListBox HorizontalAlignment="Left" Margin="54,35,0,0" Name="resultsbox" VerticalAlignment="Top" Width="382" Visibility="Collapsed">
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding nameElement, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>

Related

Effecting a Label from one Tabitem of a Tabcontrol from a button from another Tabitem of the Same Tabcontrol (using MVVM, WPF)

My Situation:
I'm trying to affect a label from one TabItem of a TabControl by clicking a Button on another TabItem of the same TabControl.
I'm currently having a hard time figuring out why the property of my TextBox textBoxTyp won't change its value even after updating the property. The binding is correct an a button right next to the TextBox (on the same TabItem) that's bound exactly like the other Button from the other `Tabitem, works perfectly fine. I'm using the MVVM pattern and databinding.
Here the code of the TabControl itself
<TabControl Name="TabSpaces"
SelectedIndex="{Binding TabIndex, Mode=TwoWay, Source={StaticResource vm_Für_Typenschild}}"
Background="White" Margin="0,0,0,-4">
<TabItem DataContext="{Binding TypneschildVM, Source={StaticResource vm_Für_Typenschild}}"
FontSize="15" Foreground="White" FontWeight="Bold" Background="#401746"
Header="Datei" Margin="0,0,-60,0">
<view:DateiV/>
</TabItem>
<TabItem MouseLeftButtonDown="SelectedTypenschild" Loaded="Typenschild_Loaded"
FontSize="15" Height="50" Foreground="White" FontWeight="Bold"
Background="#401746" Header="Typenschild" BorderBrush="#FFACACAC"
Margin="56,0,-128,0">
<view:TypenschildVM Width="Auto" Height="Auto" HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" Margin="1,0"/>
</TabItem>
</TabControl>
Here the code from the view of the TabItem with the button that should affect the TextBox
<Button Command="{Binding ReadXmlAndInsertIntoDialogsIntoTypenSchild_Command, Source={StaticResource vm_Für_Typenschild}}"
FontSize="25" x:Name="button_Datei_entfernen" Foreground="White"
Content="Datei entfernen" HorizontalAlignment="Center" Margin="476,468,476,215"
VerticalAlignment="Center" Width="326" Height="70">
</Button>
Here the code from the functions that should change the property ( ReadXmlAndInsertIntoDialogsIntoTypenSchild & CompareXmlWithJsonAndInsertIntoDialog )
namespace WPF_App_RFID_SpinOff.ViewModel
{
public class TypneschildVM : INotifyPropertyChanged, ICommand
{
private string CompareXmlWithJsonAndInsertIntoDialog(string XmlFileStringToCheck, string IdFromJsonFile)
{
string ValueTopass = "";
string line = "";
StringReader StringReaderOfXmlFile = new StringReader(XmlFileStringToCheck);
while ((line = StringReaderOfXmlFile.ReadLine()) != null)
{
if (line.Contains(IdFromJsonFile) == true)
{
int IndexRightNow = line.IndexOf('V');
int IndexWhereValueStart = line.IndexOf('V');
int CounterToGetValue = 0;
for (CounterToGetValue = IndexWhereValueStart + 1; CounterToGetValue < line.Length; CounterToGetValue++)
{
if (line[CounterToGetValue] != '"' && line[CounterToGetValue] != '=' && line[CounterToGetValue] != '/' && line[CounterToGetValue] != '>')
{
ValueTopass += line[CounterToGetValue];
}
}
}
}
return ValueTopass;
// Console.WriteLine(TypenschildM_ToUse.Hardwareversion);
}
public void ReadXmlAndInsertIntoDialogsIntoTypenSchild(object parameter)
{
int OpenBracketCount = 0;
string IdFromJsonFile = "";
string StringOfJsonFile = StaticFunc.ProvideJsonFile();
string StringOfXmlFile = StaticFunc.ProvideXMLFile();
string StringOfInformationforTypenschildFromXml = GetPartOfXmlFileForTypenSchild(StringOfXmlFile);
string StringOfInformationforTypenschildFromJson = GetPartOfJsonFileForTypenSchild(StringOfJsonFile);
string BlockOfDataforCertainValue = " ";
Console.WriteLine("test");
foreach (char character in StringOfJsonFile)
{
if (character == '{')
{
OpenBracketCount++;
}
if (OpenBracketCount >= 1)
{
BlockOfDataforCertainValue += character;
if (character == '}')
{
Console.WriteLine(BlockOfDataforCertainValue);
IdFromJsonFile = lookOutForID(BlockOfDataforCertainValue);
PropTest = CompareXmlWithJsonAndInsertIntoDialog(StringOfXmlFile, IdFromJsonFile);
OnPropertyChanged("PropTest");
}
}
}
}
#region ICommandSchnittstelle
public bool CanExecute(object parameter)
{
throw new NotImplementedException();
}
public void Execute(object parameter)
{
throw new NotImplementedException();
}
#endregion
public TypneschildVM()
{
TypenschildM TypenschildM_ToUse = TypenschildM.Instance;
LeseXMLAus = new RelayCommand(ReadXMLFileForTypenschildVM, StaticFunc.enableExecute);
ReadXmlAndInsertIntoDialogsIntoTypenSchild_Command = new RelayCommand(ReadXmlAndInsertIntoDialogsIntoTypenSchild, StaticFunc.enableExecute);
startButtoon_Command = new RelayCommand(ReadXmlAndInsertIntoDialogsIntoTypenSchild, StaticFunc.enableExecute);
}
}
}
Heres The Binding of my Textbox
<TextBox IsReadOnly="True"
Text="{Binding PropTest, Source={StaticResource vm_Für_Typenschild}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
x:Name="textBoxTyp" Height="22" Margin="243,93,133,0" TextWrapping="Wrap"
VerticalAlignment="Top" Background="#FFF3F3F3" Grid.Column="2"/>

How to get chosen effect on DragDropCompleted

I have a RadTreeView (treeview) and a RadGridView (gridview). The user should be able to move elements from the gridview to the treeview and change the effect of the drag&drop action by using the shift or control key (like in Windows Explorer).
In the GiveFeedback event the effect is set according to the pressed key and also the visualization shows the expected behavior. But in the Drop event (on the treeview) and in the DragDropCompleted event (on the gridview) the effect is set to All, therefore I'm not able to decide if I have to remove the Element from the current list.
Am I missing something?
XAML:
<telerik:RadTreeView AllowDrop="True"
ItemsSource="{Binding Folders}"
SelectedItem="{Binding SelectedFolder,
Mode=TwoWay}"
SelectionMode="Single">
<telerik:RadTreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Folder}" ItemsSource="{Binding Children}">
<Grid VerticalAlignment="Center">
<TextBlock VerticalAlignment="Center"
Text="{Binding Name}"
local:TreeItemDropBehavior.IsEnabled="True" />
</Grid>
</HierarchicalDataTemplate>
</telerik:RadTreeView.Resources>
</telerik:RadTreeView>
<telerik:RadGridView Grid.Column="1"
AllowDrop="True"
AutoGenerateColumns="False"
CanUserFreezeColumns="False"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
FontSize="12"
IsFilteringAllowed="False"
IsReadOnly="True"
ItemsSource="{Binding SelectedFolder.Elements}"
RowHeight="32"
RowIndicatorVisibility="Collapsed"
SelectionMode="Multiple"
ShowGroupPanel="False"
local:GridViewDragDropBehavior.IsEnabled="True"
telerik:DragDropManager.AllowCapturedDrag="True"
telerik:DragDropManager.AllowDrag="True">
<telerik:RadGridView.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<DataTemplate x:Key="DraggedItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Dragging: " />
<TextBlock FontWeight="Bold" Text="{Binding CurrentDraggedItems.Count}" />
<TextBlock Text=" Element(s)" />
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</telerik:RadGridView.Resources>
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn Width="100"
DataMemberBinding="{Binding Name}"
Header="Name" />
<telerik:GridViewDataColumn Width="250"
DataMemberBinding="{Binding Description}"
Header="Description" />
</telerik:RadGridView.Columns>
</telerik:RadGridView>
GridViewDragDropBehavior:
public class GridViewDragDropBehavior
{
public RadGridView AssociatedControl { get; set; }
private void SubscribeToDragDropEvents()
{
DragDropManager.AddDragInitializeHandler(AssociatedControl, OnDragInitialize);
DragDropManager.AddGiveFeedbackHandler(AssociatedControl, OnGiveFeedback);
DragDropManager.AddDragDropCompletedHandler(AssociatedControl, OnDragDropCompleted);
DragDropManager.AddDragOverHandler(AssociatedControl, OnDragOver);
}
private void UnsubscribeFromDragDropEvents()
{
DragDropManager.RemoveDragInitializeHandler(AssociatedControl, OnDragInitialize);
DragDropManager.RemoveGiveFeedbackHandler(AssociatedControl, OnGiveFeedback);
DragDropManager.RemoveDragDropCompletedHandler(AssociatedControl, OnDragDropCompleted);
DragDropManager.RemoveDragOverHandler(AssociatedControl, OnDragOver);
}
private void OnDragInitialize(object sender, DragInitializeEventArgs e)
{
DropIndicationDetails details = new DropIndicationDetails();
var gridView = sender as RadGridView;
details.DragSource = gridView.ItemsSource;
var items = gridView.SelectedItems;
details.CurrentDraggedItems = items;
IDragPayload dragPayload = DragDropPayloadManager.GeneratePayload(null);
dragPayload.SetData("DraggedData", items);
dragPayload.SetData("DropDetails", details);
e.Data = dragPayload;
e.DragVisual = new DragVisual { Content = details, ContentTemplate = AssociatedControl.Resources["DraggedItemTemplate"] as DataTemplate };
e.DragVisualOffset = new Point(e.RelativeStartPoint.X + 10, e.RelativeStartPoint.Y);
e.AllowedEffects = DragDropEffects.All;
}
private void OnGiveFeedback(object sender, GiveFeedbackEventArgs e)
{
Debug.WriteLine("GridViewDragDropBehavior.OnGiveFeedback {0}", e.Effects);
e.SetCursor(Cursors.Arrow);
e.Handled = true;
}
private void OnDragDropCompleted(object sender, DragDropCompletedEventArgs e)
{
Debug.WriteLine("GridViewDragDropBehavior.OnDragDropCompleted: {0}", e.Effects);
var data = DragDropPayloadManager.GetDataFromObject(e.Data, "DraggedData") as IList;
var details = DragDropPayloadManager.GetDataFromObject(e.Data, "DropDetails");
Debug.WriteLine(e.Effects);
// Remove Element from source list if drag drop effect is move
/*if (e.Effects == DragDropEffects.Move)
{
var collection = (details as DropIndicationDetails).DragSource as IList;
foreach(var element in data)
{
collection.Remove(element);
}
}*/
}
private void OnDragOver(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
{
Debug.WriteLine("GridViewDragDropBehavior.OnDragOver: {0}", e.Effects);
e.Effects = DragDropEffects.None;
e.Handled = true;
}
}
TreeItemDropBehavior.cs:
public class TreeItemDropBehavior
{
protected virtual void Initialize()
{
DragDropManager.AddGiveFeedbackHandler(AssociatedObject, OnGiveFeedback);
DragDropManager.AddDropHandler(AssociatedObject, OnDrop);
}
protected virtual void CleanUp()
{
DragDropManager.RemoveGiveFeedbackHandler(AssociatedObject, OnGiveFeedback);
DragDropManager.RemoveDropHandler(AssociatedObject, OnDrop);
}
private void OnGiveFeedback(object sender, Telerik.Windows.DragDrop.GiveFeedbackEventArgs e)
{
Debug.WriteLine("TreeItemDropBehavior.OnGiveFeedback {0}", e.Effects);
e.SetCursor(Cursors.Arrow);
e.Handled = true;
}
private void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
{
Debug.WriteLine("TreeItemDropBehavior.OnDrop: {0}", e.Effects);
if (e.Effects != DragDropEffects.None)
{
var destinationItem = (e.OriginalSource as FrameworkElement).ParentOfType<RadTreeViewItem>();
var data = DragDropPayloadManager.GetDataFromObject(e.Data, "DraggedData") as IList;
var details = DragDropPayloadManager.GetDataFromObject(e.Data, "DropDetails") as DropIndicationDetails;
if (destinationItem != null)
{
foreach (var element in data)
{
(destinationItem.DataContext as Folder).Elements.Add(element as Element);
}
e.Handled = true;
}
}
}
}

default selection is not working in wpf

here i m using a wpf ComboBox control and binding it using the datasource.
but my combobox is unable to set default seletion of first index which i give
manualy during the time to binding. here my code shown below can any one tell me how to set default item in combox box.
//Xaml
<ComboBox Height="23" HorizontalAlignment="Left" Margin="142,11,0,0" Name="cmbProductType" VerticalAlignment="Top" Width="180" ItemsSource="{Binding}" />
//Code
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ClsControl.GetProductTypeList(cmbProductType);
}
public static void GetProductTypeList(ComboBox ddlProductType)//Add By Sandeep On 11-03-2013
{
try
{
DataTable dtProductType = null;
try
{
ClsDataLayer objDataLayer = new ClsDataLayer();
dtProductType = objDataLayer.ExecuteDataTable("COMNODE_PROC_GetProductTypeList");
if (dtProductType != null && dtProductType.Rows.Count > 0)
{
DataRow drCardType = dtProductType.NewRow();
drCardType[0] = -1;
drCardType[1] = "< -- Select Card Type -- >";
ddlProductType.SelectedValue = -1;
dtProductType.Rows.InsertAt(drCardType, 0);
ddlProductType.ItemsSource = dtProductType.DefaultView;
ddlProductType.DisplayMemberPath = "PRODUCT_TYPE";
ddlProductType.SelectedValuePath = "PRODUCT_TYPE_ID";
}
}
catch (Exception)
{
throw;
}
}
catch
{
}
}
Try updating your XAML to this:
<ComboBox Height="23"
HorizontalAlignment="Left"
Margin="142,11,0,0"
Name="cmbProductType"
VerticalAlignment="Top"
Width="180"
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True" />
Also, use SelectedIndex instead when you select the item:
ddlProductType.SelectedIndex = 0;
dtProductType.Rows.InsertAt(drCardType, 0);
ddlProductType.ItemsSource = dtProductType.DefaultView;
ddlProductType.DisplayMemberPath = "PRODUCT_TYPE";
ddlProductType.SelectedValuePath = "PRODUCT_TYPE_ID"

mvvm:listview selected item fired when ItemsSource get value

I am new to MVVM I have scenario I have One textbox and One Listview .When textbox text(PONo) changed , the listview get populated with some data (PORecords) by filtering through the text.
My View is:
<TextBox Height="24"
VerticalAlignment="Top"
Width="119"
Text="{Binding Path=PONo,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
/>
<ListView Height="161"
ItemsSource="{Binding Path=PORecords}"
SelectedItem="{Binding Path=SelectedPO,Mode=TwoWay}"
IsSynchronizedWithCurrentItem="True"
Visibility="{Binding Path=PORecords,Converter={StaticResource ResourceKey=NullToVisibilityConverter}}"
Width="357">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=PurchaseOrderRefNo}"
Header="Order No"
Width="100" />
<GridViewColumn DisplayMemberBinding="{Binding Path=OrderDate, StringFormat=dd-MMM-yyyy}"
Header="Order Date"
Width="100" />
</GridView>
</ListView.View>
</ListView>
My ViewModel is:
private string _pONo;
public string PONo
{
get { return _pONo; }
set
{
if (value != "" && value!=null)
{
_pONo = value;
List<Tbl_PurchaseOrderMain> _lst = new List<Tbl_PurchaseOrderMain>();
_lst = new Tbl_PurchaseOrderMain().Select(" PurchaseOrderRefNo like '" + _pONo + "%'");
if (_lst.Count != 0)
{
PORecords = _lst;
}
else
{
PORecords = null;
}
}
else
{
PORecords = null;
}
RaisePropertyChanged("PONo");
}
}
private List<Tbl_PurchaseOrderMain> _pORecords;
public List<Tbl_PurchaseOrderMain> PORecords
{
get { return _pORecords; }
set
{
_pORecords = value;
RaisePropertyChanged("PORecords");
}
}
private Tbl_PurchaseOrderMain _selectedPO;
public Tbl_PurchaseOrderMain SelectedPO
{
get { return _selectedPO; }
set
{
_selectedPO = value;
if (SelectedPO != null)
{
PONo = SelectedPO.PurchaseOrderRefNo;
}
else
{
PONo = null;
}
RaisePropertyChanged("SelectedPO");
}
}
My problem is that when I enter text on textbox it will populate the listview (PORecords) with three Items.On that moment the selectedPO property is also fired then the textBox is filled the PONo but my listview then have only one Item the other two item gone .Actually I dont select any item on the Listview.I want to populate the textbox only when I select an Item from the listview whats wrong with my code any body have idea?

How to access a specific item in a Listbox with DataTemplate?

I have a ListBox including an ItemTemplate with 2 StackPanels.
There is a TextBox in the second StackPanel i want to access.
(Change it's visibility to true and accept user input)
The trigger should be the SelectionChangedEvent. So, if a user clicks on an ListBoxItem, the TextBlock gets invisible and the TextBox gets visible.
XAML CODE:
<ListBox Grid.Row="1" Name="ContactListBox" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Contacts}" Margin="0,36,0,0" SelectionChanged="ContactListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Edit Contact" Click="ContactMenuItem_Click"/>
<toolkit:MenuItem Header="Delete Contact" Click="ContactMenuItem_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<Grid>
<Rectangle Fill="{StaticResource PhoneAccentBrush}"
Width="72" Height="72">
<Rectangle.OpacityMask>
<ImageBrush ImageSource="/Images/defaultContactImage.png" Stretch="UniformToFill"/>
</Rectangle.OpacityMask>
</Rectangle>
</Grid>
<StackPanel>
<TextBox Text="{Binding Name}" TextWrapping="Wrap" Visibility="Collapsed"/>
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" />
<TextBlock Text="{Binding Number}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextAccentStyle}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I guess there are several ways to solve this, but nothing I tried worked.
My current approach looks like this
private void ContactListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBoxItem listBoxItem = ContactListBox.SelectedItem as ListBoxItem;
DataTemplate listBoxTemplate = listBoxItem.ContentTemplate;
// How to access the DataTemplate content?
StackPanel outerStackPanel = listBoxTemplate.XXX as StackPanel;
StackPanel innerStackPanel = outerStackPanel.Children[1] as StackPanel;
TextBox nameBox = innerStackPanel.Children[0] as TextBox;
TextBlock nameBlock = innerStackPanel.Children[1] as TextBlock;
nameBox.Visibility = System.Windows.Visibility.Visible;
nameBlock.Visibility = System.Windows.Visibility.Collapsed;
}
Thank you for your help guys!! Finally i got it. Solved the problem with the VisualTreeHelper. What a great function ^^
private void ContactListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ContactListBox.SelectedIndex == -1)
return;
currentSelectedListBoxItem = this.ContactListBox.ItemContainerGenerator.ContainerFromIndex(ContactListBox.SelectedIndex) as ListBoxItem;
if (currentSelectedListBoxItem == null)
return;
// Iterate whole listbox tree and search for this items
TextBox nameBox = helperClass.FindDescendant<TextBox>(currentSelectedListBoxItem);
TextBlock nameBlock = helperClass.FindDescendant<TextBlock>(currentSelectedListBoxItem);
helperFunction
public T FindDescendant<T>(DependencyObject obj) where T : DependencyObject
{
// Check if this object is the specified type
if (obj is T)
return obj as T;
// Check for children
int childrenCount = VisualTreeHelper.GetChildrenCount(obj);
if (childrenCount < 1)
return null;
// First check all the children
for (int i = 0; i < childrenCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child is T)
return child as T;
}
// Then check the childrens children
for (int i = 0; i < childrenCount; i++)
{
DependencyObject child = FindDescendant<T>(VisualTreeHelper.GetChild(obj, i));
if (child != null && child is T)
return child as T;
}
return null;
}
With this edited function you can also search for control by name (its converted from VB.NET):
public T FindDescendantByName<T>(DependencyObject obj, string objname) where T : DependencyObject
{
string controlneve = "";
Type tyype = obj.GetType();
if (tyype.GetProperty("Name") != null) {
PropertyInfo prop = tyype.GetProperty("Name");
controlneve = prop.GetValue((object)obj, null);
} else {
return null;
}
if (obj is T && objname.ToString().ToLower() == controlneve.ToString().ToLower()) {
return obj as T;
}
// Check for children
int childrenCount = VisualTreeHelper.GetChildrenCount(obj);
if (childrenCount < 1)
return null;
// First check all the children
for (int i = 0; i <= childrenCount - 1; i++) {
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child is T && objname.ToString().ToLower() == controlneve.ToString().ToLower()) {
return child as T;
}
}
// Then check the childrens children
for (int i = 0; i <= childrenCount - 1; i++) {
string checkobjname = objname;
DependencyObject child = FindDescendantByName<T>(VisualTreeHelper.GetChild(obj, i), objname);
if (child != null && child is T && objname.ToString().ToLower() == checkobjname.ToString().ToLower()) {
return child as T;
}
}
return null;
}
I can't give you a complete answer...
But I think you can use the VisualTreeHelper to iterate through the children of any control
http://blogs.msdn.com/b/kmahone/archive/2009/03/29/visualtreehelper.aspx
However, for the effect you are looking for, then I think using the SelectedItem Style might be a better solution - e.g. see this article - http://joshsmithonwpf.wordpress.com/2007/07/30/customizing-the-selected-item-in-a-listbox/
Use ItemContainerGenerator.
private void ContactListBox_SelectionChanged
(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 1)
{
var container = (FrameworkElement)ContactListBox.ItemContainerGenerator.
ContainerFromItem(e.AddedItems[0]);
StackPanel sp = container.FindVisualChild<StackPanel>();
TextBox tbName = (TextBox) sp.FindName("tbName");
TextBlock lblName = (TextBlock)sp.FindName("lblName");
TextBlock lblNumber = (TextBlock)sp.FindName("lblNumber");
}
}
Since DataTemplate is a generic template that could be used many times in the code, there is no way to access it by name (x:Name="numberTextBox").
I solved similar problem to this by making a collection of Controls - while Listbox was populating I add Textbox control to the collection.
string text = myCollectionOfTextBoxes[listbox.SelectedIndex].Text;
Till I found a better soultion - Tag property. In your ListboxItem you bind Tag property to the name
Tag="{Binding Name}"
and the to access it
ListBoxItem listBoxItem = ContactListBox.SelectedItem as ListBoxItem;
string name = listBoxItem.Tag.ToString();

Categories