I have treeview inside my Listview like below
<ListView x:Name="LvItemDisplay" ItemsSource="{Binding itemDisplayList}" SelectionChanged="LvItemDisplay_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate x:Name="dtItemDisplay">
<TreeView x:Name="TvItemDisplay" Background="Transparent" ItemsSource="{Binding itemDisplayList}" MouseDown="TvItemDisplay_MouseDown_1" SelectedItemChanged="TvItemDisplay_SelectedItemChanged" >
.
.
.
I have click event for both treeview and listview. both of it when click it will popup a dialog box that user can edit that will binding from them.
the problem is, whenever user want to click the treeview user need to click on the listview first to get the SelectedItem. if not nothing will happen since the SelectedItem will be null.
this is the code behind for listview
private void LvItemDisplay_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListViewItem listViewItem = (ListViewItem)(LvItemDisplay.ItemContainerGenerator.ContainerFromItem(LvItemDisplay.SelectedItem));
TreeView treeView = null;
DialogHost dialogHost = null;
if (LvItemDisplay.SelectedIndex != -1)
{
if (listViewItem != null)
{
//get the listViewItem's template parent
ContentPresenter templateParent = GetFrameworkElementByName<ContentPresenter>(listViewItem);
//get the DataTemplate that treeview in.
DataTemplate dataTemplate = LvItemDisplay.ItemTemplate;
if (dataTemplate != null && templateParent != null)
{
treeView = dataTemplate.FindName("TvItemDisplay", templateParent) as TreeView;
if (treeView != null)
{
dialogHost = dataTemplate.FindName("dialogBoxEditQty", templateParent) as DialogHost;
dialogHost.IsOpen = true;
}
}
}
}
}
and for treeview
private void TvItemDisplay_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
ListViewItem listViewItem = (ListViewItem)(LvItemDisplay.ItemContainerGenerator.ContainerFromItem(LvItemDisplay.SelectedItem));
TreeView treeView = null;
DialogHost dialogHost = null;
if (listViewItem != null)
{
//get the listViewItem's template parent
ContentPresenter templateParent = GetFrameworkElementByName<ContentPresenter>(listViewItem);
//get the DataTemplate that treeview in.
DataTemplate dataTemplate = LvItemDisplay.ItemTemplate;
if (dataTemplate != null && templateParent != null)
{
treeView = dataTemplate.FindName("TvItemDisplay", templateParent) as TreeView;
}
if (treeView != null)
{
dialogHost = dataTemplate.FindName("dialogBoxEditQty", templateParent) as DialogHost;
dialogHost.IsOpen = true;
}
}
}
save for dialogHost
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
try
{
// get the current selected item
ListViewItem listViewItem = (ListViewItem)(LvItemDisplay.ItemContainerGenerator.ContainerFromItem(LvItemDisplay.SelectedItem));
DialogHost dialogHost = null;
if (listViewItem != null)
{
.
.
.
I want something like whenever user click on the treeview it will triggered the listview behind /click the listview as well. is it possible ?
You can manualy select the ListView Item
TreeView Selection Changed
private void TvItemDisplay_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
LvItemDisplay.SelectionChanged -= LvItemDisplay_SelectionChanged;
ParentItemSelectionChange(sender, true);
// Your code
ParentItemSelectionChange(sender, false);
LvItemDisplay.SelectionChanged += LvItemDisplay_SelectionChanged;
}
Helper Methods
private FrameworkElement ParentItemSelectionChange(object sender, bool selChange)
{
var frameworkElement = sender as FrameworkElement;
if (frameworkElement != null)
{
var item = FindParent<ListViewItem>(frameworkElement);
if (item != null)
item.IsSelected = selChange;
}
return frameworkElement;
}
public T FindParent<T>(DependencyObject child) where T : DependencyObject
{
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null) return null;
T parent = parentObject as T;
if (parent != null)
return parent;
return FindParent<T>(parentObject);
}
Related
private void DisableControl(Control control)
{
foreach (Control childControl in divPanelAdd.Controls)
{
var textbox = control as TextBox;
if (textbox != null || textbox == null)
textbox.Enabled= false;
var dropDownList = control as DropDownList;
if (dropDownList != null || dropDownList == null)
dropDownList.Enabled = false;
DisableControl(childControl);
}
}
I'm using for each loop to enable or disable of "divPanelAdd" div but it shows nullexception error.help me to solve this.
Try this:
private void DisableControl() {
foreach (Control childControl in divPanelAdd.Controls) {
if (childControl.GetType() == typeof(TextBox) || childControl.GetType() == typeof(DropDownList))
((WebControl)childControl).Enabled = false;
}
}
private void SomeEventHandler(object Sender, EventArgs e)
{
DisableControl(divPanelAdd)
}
// Disable textboxes and dropdowns (recusively) under parent.
private void DisableControl(Control parent)
{
foreach (Control child in parent.Controls)
{
var textbox = child as TextBox;
if (textbox != null)
{
textbox.Enabled = false;
}
else
{
var dropDownList = child as DropDownList;
if (dropDownList != null)
{
dropDownList.Enabled = false;
DisableControl(dropDownList);
}
}
}
}
You did intend for this to be recursive? If so the for shouldn't the for loop refer to the control passed in not divPanel. divPanel add can be the first parent passed in from somewhere else.
I would like to get the column name of the cell the same way i did with its content on my loose focus method.I can get the content but not the column header.
private void lostFocus(object sender, RoutedEventArgs e)
{
var jj = sender as DataGridColumnHeader;
var box = sender as TextBox;
if (box != null && box.Text != "0")
{
var ff = jj.Column.Header.ToString();
if (ff == "column1") { amount1 = Int32.Parse(box.Text); }
if (ff == "column2") { amount2 = Int32.Parse(box.Text); }
if (ff == "column3") {amount3 = Int32.Parse(box.Text); }
}
else
{
}
}
xaml code
<toolkit:DataGridTemplateColumn Header="column1" Width="8*">
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Padding="0" LostFocus="OnGotFocus" GotFocus="OnGotFocus" />
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>
Getting column header
What you need is already provided here by Fredrik. Basically you need to get all the children of type DataGridColumnHeader existing in the DataGrid. Check the column reference and then get the header.
Further more, i see you are getting the DataGridColumnHeader from sender. In order to reach the DataGrid object you can use a helper method :
public static T FindParent<T>(DependencyObject child) where T : DependencyObject
{
//get parent item
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
return parent;
else
return FindParent<T>(parentObject);
}
Use it like this:
DataGrid parentGrid = FindParent<DataGrid>(sender as DataGridColumnHeader );
or starting from TextBox
DataGrid parentGrid = FindParent<DataGrid>(sender as TextBox);
I am not exactly sure about your scenario.
Updated Xamal... set the textbox name to be the same as header name
<toolkit:DataGridTemplateColumn Header="column1" Width="8*">
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Padding="0" Name="column1" LostFocus="OnGotFocus" />
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>
then just got the name from my sender.... simplicity works
private void lostFocus(object sender, RoutedEventArgs e)
{
var box = sender as TextBox;
if (box != null && box.Text != "0")
{
var name = box.Name.ToString();
if (name == "column1") { amount1 = Int32.Parse(box.Text); }
if (name == "column2") { amount2 = Int32.Parse(box.Text); }
if (name == "column3") {amount3 = Int32.Parse(box.Text); }
}
else
{
}
}
Thanks for the help https://stackoverflow.com/users/2047469/olaru-mircea
I have datagrid template and some textbox control into each row at datagrid.
So, how to drag and drop into textbox on row?
I know how and what i should drop, but i do not know how to get the position of datagrid item that i should drop.
You can use the VisualTreeHelper.HitTest method and the VisualTreeHelper.GetParent method to find out if you're over a particular DataGridRow in the PreviewDragOver event handler:
private void PreviewDragOver(object sender, DragEventArgs e)
{
HitTestResult hitTestResult =
VisualTreeHelper.HitTest(sender, e.GetPosition(sender));
DataGridRow dataGridRowUnderMouse =
GetParentOfType<DataGridRow>(hitTestResult.VisualHit);
// Do something with dataGridRowUnderMouse
}
private T GetParentOfType<T>(DependencyObject element) where T : DependencyObject
{
Type type = typeof(T);
if (element == null) return null;
DependencyObject parent = VisualTreeHelper.GetParent(element);
if (parent == null && ((FrameworkElement)element).Parent is DependencyObject)
parent = ((FrameworkElement)element).Parent;
if (parent == null) return null;
else if (parent.GetType() == type || parent.GetType().IsSubclassOf(type))
return parent as T;
return GetParentOfType<T>(parent);
}
I have a Listbox which items can be open & view by following code...
private void AccountsList_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var listBoxItem = AccountsList.ItemContainerGenerator.ContainerFromIndex(AccountsList.SelectedIndex) as ListBoxItem;
var txtBlk = FindVisualChildByType<TextBlock>(listBoxItem, "txtBlkAccountName");
xCa = txtBlk.Text;
NavigationService.Navigate(new Uri(string.Format("/ViewAccount.xaml?parameter={0}&action={1}", a.ToString(), "View"), UriKind.Relative));
}
&
T FindVisualChildByType<T>(DependencyObject element, String name) where T : class
{
if (element is T && (element as FrameworkElement).Name == name)
{
return element as T;
}
int childcount = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < childcount; i++)
{
T childElement = FindVisualChildByType<T>(VisualTreeHelper.GetChild(element, i), name);
if (childElement != null)
{
return childElement;
}
}
return null;
}
now i am implementing longlistselector instead of the listbox.
Long List Selector shows all my items from database but i am having problem while opening an item from this list... i cant use SelectedIndex in this longlistselector PLEASE HELP...
I would suggest you change your workflow. Instead of listening to the Tap event, listen to the SelectionChanged event. From this event you can get the SelectedItem. The SelectItem is the object the Items are bound to.
Example: Your ItemsSource is List each item within the ListBox or LongListSelector is bound to an instance of MyObject. Your "txtBlkAccountName" TextBlock should have it's Text bound to the AccountNumber property of your MyObject class.
private void LongListSelector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var myObj = AccountsList.SelectedItem as MyObject;
if(myObj == null) return;
var accountNum = myObj.AccountNumber;
NavigationService.Navigate(new Uri(string.Format("/ViewAccount.xaml?parameter={0}&action={1}", accountNum, "View"), UriKind.Relative));
// set the selectedItem to null so the page can be navigated to again
// If the user taps the same item
AccountsList.SelectedItem = null;
}
To get the item tapped, place the Tap even inside the ItemTemplate not the List, then you can use the sender property to retrieve the value you want.
Also instead of using FindVisualChildByType to get the value you want you should be able to just use the DataContext to retrieve whatever you want:
private void AccountsItem_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
FrameworkElement element=sender as FrameworkElement ;
Account item= element.DataContext as Account ;
xCa = item.Name;
NavigationService.Navigate(new Uri(string.Format("/ViewAccount.xaml?parameter={0}&action={1}", a.ToString(), "View"), UriKind.Relative));
}
I am trying to get a cell value from the selected item of a silverlight datagrid. In the attached code I can get to the properties of the cell and change its forecolor, but I can not get the value of the cell. Can someone please let me know what I am doing wrong? Many thanks in advance for your help!
private void FindDetails_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DataGrid dataGrid = sender as DataGrid;
int selectedIndex = dataGrid.SelectedIndex;
if (selectedIndex > -1)
{
FindResult findResult = (FindResult)FindDetailsDataGrid.SelectedItem;
DataGridColumn column = dataGrid.Columns[0];
FrameworkElement fe = column.GetCellContent(dataGrid.SelectedItem);
FrameworkElement result = GetParent(fe, typeof(DataGridCell));
if (result != null)
{
DataGridCell cell = (DataGridCell)result;
//changes the forecolor
cell.Foreground = new SolidColorBrush(Colors.Blue);
//how to get cell value?
}
}
}
private FrameworkElement GetParent(FrameworkElement child, Type targetType)
{
object parent = child.Parent;
if (parent != null)
{
if (parent.GetType() == targetType)
{
return (FrameworkElement)parent;
}
else
{
return GetParent((FrameworkElement)parent, targetType);
}
}
return null;
}
Thanks VooDooChild, see below for my solution using the textblock to get at value.
private void FindDetails_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DataGrid dataGrid = sender as DataGrid;
int selectedIndex = dataGrid.SelectedIndex;
if (selectedIndex > -1)
{
FindResult findResult = (FindResult)FindDetailsDataGrid.SelectedItem;
DataGridColumn column = dataGrid.Columns[0];
FrameworkElement fe = column.GetCellContent(dataGrid.SelectedItem);
FrameworkElement result = GetParent(fe, typeof(DataGridCell));
if (result != null)
{
DataGridCell cell = (DataGridCell)result;
//changes the forecolor
cell.Foreground = new SolidColorBrush(Colors.Blue);
//how to get cell value?
TextBlock block = fe as TextBlock;
if (block != null)
{
string cellText = block.Text;
MessageBox.Show(cellText);
}
}
}
}
private void FindDetails_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
DataGrid dataGrid = sender as DataGrid;
var item = dataGrid.SelectedItem;
if (item != null)
{
//in here you can get the properties with the "item"'s object
}
}
Have you tried something like this pseudo:
string myString = ((MyNamespace.MyEntity)(myDataGrid.SelectedItem)).myStringProperty;
Try cell.Content
http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.aspx