<ListView Height="Auto" Name="lstIndent" SelectionMode="Single" Grid.ColumnSpan="5" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Row="0" >
<ListView.View >
<GridView x:Name="dgIndentDetails" >
<GridViewColumn Width="Auto" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<!--<GroupBox Header="Department Issue Header" Grid.Row="5" Grid.ColumnSpan="5" HorizontalAlignment="Stretch" >-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding Path=IsIndentIssue, UpdateSourceTrigger=PropertyChanged}" x:Name="chkbxIsChecked" HorizontalAlignment="Center"/>
<Label Grid.Column="1" Grid.Row="0" Content="{Binding ItemName}" x:Name="lbllstItemName" HorizontalAlignment="Center" ></Label>
<Label Grid.Column="2" Grid.Row="0" Content="{Binding Quantity}" x:Name="lbllstQty" HorizontalAlignment="Center" ></Label>
<Label Grid.Column="3" Grid.Row="0" Content="{Binding IssueQuantity}" x:Name="lbllstIssuedQty" HorizontalAlignment="Center" ></Label>
<DataGrid Height="Auto" Padding="10,10,10,10" Width="800" Grid.Row="1" Grid.ColumnSpan="5" Name="dgIssuedItemsBatchDetails" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ItemName}">
<DataGridTextColumn.Header>
<TextBlock Text="ItemName"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding BatchNo}">
<DataGridTextColumn.Header>
<TextBlock Text="BatchNo"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Quantity}">
<DataGridTextColumn.Header>
<TextBlock Text="Quantity"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
<!--</GroupBox>-->
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I need to find DataGrid dgIssuedItemsBatchDetails and then bind. That DataGrid is placed inside GridView and that GridView is placed inside ListView.
GridView grdvwIssueDetail = (GridView)lstIndent.FindName("dgIndentDetails");
By using this code I am able to find the GridView. My DataGrid is placed inside GridView DataTemplate. So suggest me how I can find my DataGrid from code behind.
It can be achieved by using VisualTreeHelper.
As MSDN says:
VisualTreeHelper class provides utility methods that perform common tasks involving nodes in a visual tree.
So let me show an example how it can be achieved:
private void SeeTheChild()
{
DataGrid myCombo = GetVisualChildInDataTemplate<DataGrid>(lstIndent);
}
private T GetVisualChildInDataTemplate<T>(DependencyObject parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChildInDataTemplate<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}
VisualTreeHelper.GetChildrenCount(parent) returns 0 cause ListView is created, but not yet loaded. Particularly, the DataTemplate has not yet been applied to the ListView, consequently there is nothing in the Visual Tree.
Then use this method to get your DataGrid on Loaded event of your Window:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
SeeTheChild();
}
Update:
To find a control per item in ListView:
Create a SelectionChanged event:
private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ItemContainerGenerator generator = this.listView.ItemContainerGenerator;
ListBoxItem selectedItem = (ListBoxItem)generator.ContainerFromIndex(listView.SelectedIndex);
Label aLabel = GetChildrenByType(selectedItem, typeof(Label), "label") as Label;
if (aLabel != null)
{
MessageBox.Show("We've found Label with name 'label': " + aLabel.Content);
}
else
{
MessageBox.Show("There is no such Label");
}
}
and a method which can find a necessary control for you:
public static Visual GetChildrenByType(Visual visualElement, Type typeElement, string nameElement)
{
if (visualElement == null) return null;
if (visualElement.GetType() == typeElement)
{
FrameworkElement fe = visualElement as FrameworkElement;
if (fe != null)
{
if (fe.Name == nameElement)
{
return fe;
}
}
}
Visual foundElement = null;
if (visualElement is FrameworkElement)
(visualElement as FrameworkElement).ApplyTemplate();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visualElement); i++)
{
Visual visual = VisualTreeHelper.GetChild(visualElement, i) as Visual;
foundElement = GetChildrenByType(visual, typeElement, nameElement);
if (foundElement != null)
break;
}
return foundElement;
}
Related
I have create simple drag drop in WPF. In my application there are two Listviews. I have to drag list items from first listview and drop the item to second listview. I have created custom data template for first listview. When i drag the first listview item into second listview the data template is not customized so items are not displayed. How to display the list items with generic. Please help. My Code is as below,
<Grid Margin="0,20,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ListBox
Name="memberCollection"
Grid.Column="1"
Width="150"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
PreviewMouseLeftButtonDown="memberCollection_PreviewMouseLeftButtonDown">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid
Name="gridDrop"
Grid.Column="0"
Margin="20,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ListBox.Drop="grid_Drop"
ShowGridLines="True">
<ListBox
Grid.Row="0"
Grid.Column="0"
Margin="10,10,0,0"
AllowDrop="True" />
</Grid>
</Grid>
Code Behind
ObservableCollection<Member> member = new ObservableCollection<Member>();
public MainWindow()
{
InitializeComponent();
member.Add(new Member { Name = "Karthick", ID = "20011", Address = "10, MainRoad, Chennai" });
memberCollection.ItemsSource = member;
DataContext = new Member();
}
private void memberCollection_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
object selectedMember = memberCollection.SelectedItem as Member;
if (selectedMember != null)
DragDrop.DoDragDrop(memberCollection, selectedMember, DragDropEffects.All);
}
private void grid_Drop(object sender, RoutedEventArgs e)
{
ListBox listContent = e.Source as ListBox;
if (listContent != null)
Console.WriteLine("", Grid.GetColumn(listContent), Grid.GetRow(listContent));
DataObject item = (((DragEventArgs)e).Data) as DataObject;
object Target = ((Grid)(sender)).DataContext;
object listItem = item.GetData(Target.GetType());
if (listItem != null)
{
//listContent.Items.Add(listItem.Name.ToString());
//listContent.Items.Add(listItem.ID.ToString());
//listContent.Items.Add(listItem.Address.ToString());
//listContent.ItemTemplate = memberCollection.ItemTemplate;
listContent.Items.Add(listItem);
}
}
If you define the DataTemplate as a reusable resource, you can use it in both ListBoxes:
<Grid Margin="0,20,0,0">
<Grid.Resources>
<DataTemplate x:Key="dataTemplate">
<StackPanel>
<TextBox Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ListBox
Name="memberCollection"
Grid.Column="1"
Width="150"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
PreviewMouseLeftButtonDown="memberCollection_PreviewMouseLeftButtonDown"
ItemTemplate="{StaticResource dataTemplate}" />
<Grid
Name="gridDrop"
Grid.Column="0"
Margin="20,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ListBox.Drop="grid_Drop"
ShowGridLines="True">
<ListBox
Grid.Row="0"
Grid.Column="0"
Margin="10,10,0,0"
AllowDrop="True"
ItemTemplate="{StaticResource dataTemplate}"/>
</Grid>
</Grid>
If you want to display some other properties of the dropped Member in the second ListBox, you should define another ItemTemplate:
<ListBox
Grid.Row="0"
Grid.Column="0"
Margin="10,10,0,0"
AllowDrop="True">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Id}" />
<TextBlock Tag="{Binding Address}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I am fairly new to coding and I am building a database UI.
What I need to do is click on a row in a listview and get the return of the Id.
Below is the code I have but it gets an 'Exception User-Unhandled System.ArgumentNullException: value cannot be null'.
Any help will be predicated.
UWP Xaml <ListView x:Name="ListItems" IsItemClickEnabled="True" ItemClick="ListItems_ItemClick" Tag="{Binding Id}"
>
private void ListItems_ItemClick(object sender, ItemClickEventArgs e)
{
var id = (sender as ListView).Tag as string;
{
testbox.Text = id;
}
Full List View
<ListView x:Name="ListItems" IsItemClickEnabled="True" ItemClick="ListItems_ItemClick" Tag="{Binding Id}"
>
<ListView.ItemTemplate >
<DataTemplate >
<Border
BorderThickness="0,0,0,0">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="130" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Padding" Value="8,0,0,0" />
</Style>
</Grid.Resources>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Stretch"
Text="{Binding LegalName, Mode=OneWay}" />
<TextBlock
Grid.Column="1"
HorizontalAlignment="Stretch"
Text="{Binding PhoneNumber, Mode=OneWay}" />
<TextBlock
Grid.Column="2"
HorizontalAlignment="Stretch"
Text="{Binding EmailAddress, Mode=OneWay}" />
<TextBlock
Grid.Column="3"
HorizontalAlignment="Stretch"
Text="{Binding HomeAddress, Mode=OneWay}" />
<TextBlock
Grid.Column="4"
HorizontalAlignment="Stretch"
Text="{Binding PostalAddress, Mode=OneWay}" />
<TextBlock
Grid.Column="5"
HorizontalAlignment="Stretch"
Text="{Binding Id, Mode=OneWay}" />
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here's a very easy approach. Bind the TextChanged event of all the texboxes to a TextChanged event :
XAML
<TextBlock Grid.Column="0" TextChanged="textbox_TextChanged".../>
C#
private string selectedText;
private void textbox_TextChanged(object sender, EventArgs e)
{
selectedtext = (sender as TextBlock).Text
}
private void ListItems_ItemClick(object sender, ItemClickEventArgs e)
{
///use selectedtext string as you want
}
do it Like that
1 - do not bind id to list-view Tag because it is Object.
2 - get your id like that
private void ListItems_ItemClick(object sender, ItemClickEventArgs e)
{
if ((e != null) && (e.Item != null))
{
var selected = (lsv.SelectedItem as yourClassType);
var yorItemID=selected .id;
}
}
I have this code:
<HubSection x:Name="MyHub">
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="200"></RowDefinition>
</Grid.RowDefinitions>
<Image x:Name="MYImage" Source="{Binding image}" Height="50" Width="60" VerticalAlignment="Center"/>
<StackPanel Orientation="Vertical">
<TextBlock TextWrapping="Wrap" Width="200" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding name}"/>
<Button Content="Click me">
</StackPanel>
</Grid>
</DataTemplate>
</HubSection>
But I do not know how to access the text-block, I want to change the foreground color of the text-block in code behind.
XAML:
<Hub x:Name="myHub">
<HubSection x:Name="myHubSection">
<DataTemplate>
<TextBlock x:Name="textbox1" Text="text" Width="300" Height="100">
</TextBlock>
</DataTemplate>
</HubSection>
</Hub>
Code behind:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var hub_section = FindVisualChildByName<HubSection>(this.myHub, "myHubSection");
var text_box = FindVisualChildByName<WebView>(hub_section, "textbox1");
}
public static T FindVisualChildByName<T>(DependencyObject parent, string name)where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
string controlName = child.GetValue(Control.NameProperty) as string;
if (controlName == name)
{
return child as T;
}
else
{
T result = FindVisualChildByName<T>(child, name);
if (result != null)
return result;
}
}
return null;
}
More detailed information you could refer to How to access a Control inside the data template in C# Metro UI in the code behind
my xaml code..
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="DataTemplate1" >
<Border BorderBrush="LightGray" BorderThickness="1" Height="150" Width="500" >
<Grid Width="500" Height="150" Background="White" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.9*"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="1.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Name="imgitem" Grid.Column="0" Height="Auto" Width="Auto" Source="{Binding ImgSource}" Margin="0,5,4,4" HorizontalAlignment="Left" />
<TextBlock x:Name="txtbindprice" Text="{Binding _PRICE,ConverterCulture=en-IN,StringFormat=C}" TextWrapping="Wrap" Grid.Column="1" Width="350" Foreground="Black" Height="60" Margin="40,70,20,-10"/>
<TextBlock x:Name="txtFinalTotal" Text="{Binding _FinalTotal}" TextWrapping="Wrap" Grid.Column="1" Width="350" Foreground="Red" Height="60" Margin="40,115,20,-10"/>
<TextBlock x:Name="txtITMNAME" Text="{Binding _ITMNAME }" Padding="1" Tap="ItmName_Tapped" TextDecorations="Underline" FontSize="24" TextWrapping="Wrap" Grid.Column="1" FontWeight="Normal" TextTrimming="WordEllipsis" Foreground="OrangeRed" Width="Auto" Height="150" Margin="30,25,10,-10"/>
<CheckBox Grid.Column="2" Grid.Row="0" Background="Black" Foreground="Black" BorderThickness="4" BorderBrush="Red" Margin="10,20,-15,10" Checked="CheckBox_Checked" Unchecked="CheckBox_UnChecked" />
</Grid>
</Border>
</DataTemplate>
<ListBox Height="Auto" Name="lstbxmanual" SelectionMode="Extended" ItemTemplate="{StaticResource DataTemplate1 }" Width="475" Margin="2,192,0,-39" Background="White" HorizontalAlignment="Left" Grid.RowSpan="2">
</ListBox>
I want to access textblocks inside listbox based on selected index
accessing textblock
string a =txtbindprice.text
wont work as they are inside data template of listbox..
I came across visual child tree methods and some other examples..i cant find much info..
please help me regarding this...
The following method finds currently selected list-box item:
private ListBoxItem FindSelectedListBoxItem(DependencyObject control)
{
int childNumber = VisualTreeHelper.GetChildrenCount(control);
for (int i = 0; i < childNumber; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(control, i);
FrameworkElement fe = child as FrameworkElement;
// Not a framework element or is null
if (fe == null) return null;
if (child is ListBoxItem && ((ListBoxItem)child).IsSelected)
{
// Found the control so return
return (ListBoxItem)child;
}
else
{
// Not found it - search children
ListBoxItem nextLevel = FindSelectedListBoxItem(child);
if (nextLevel != null)
return nextLevel;
}
}
return null;
}
Below method finds any child control with a certain name from a given root control:
private DependencyObject FindChildControl<T>(DependencyObject control, string ctrlName)
{
int childNumber = VisualTreeHelper.GetChildrenCount(control);
for (int i = 0; i < childNumber; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(control, i);
FrameworkElement fe = child as FrameworkElement;
// Not a framework element or is null
if (fe == null) return null;
if (child is T && fe.Name == ctrlName)
{
// Found the control so return
return child;
}
else
{
// Not found it - search children
DependencyObject nextLevel = FindChildControl<T>(child, ctrlName);
if (nextLevel != null)
return nextLevel;
}
}
return null;
}
Now you can use the first method to get currently selected ListBoxItemand then pass it to the second method to retrieve any control inside this ListBoxItem (e.g. txtbindprice):
ListBoxItem item = FindSelectedListBoxItem(this);
TextBlock txtPrice = FindChildControl<TextBlock>(item , "txtbindprice") as TextBlock;
string a = txtPrice.Text;
Update
You can add SelectionChanged event to your ListBox like this:
<ListBox Height="Auto" Name="lstbxmanual" SelectionChanged="OnSelectionChanged">
</ListBox>
And then retrieve a certain TextBlock.Text (e.g. txtbindprice) this way:
public void OnSelectionChanged(object sender, SelectionChangedEventArgs args)
{
ListBoxItem item = FindSelectedListBoxItem((ListBox(sender)));
TextBlock txtPrice = FindChildControl<TextBlock>(item , "txtbindprice") as TextBlock;
string a = txtPrice.Text;
}
I am working on silverlight and I am new in it, I have a combox box,inside which I have a checkbox and textbox. I want to get the value of these controls on button click, How can I do this in SilverLight?
This is my ComboBox
<ComboBox x:Name="Type" VerticalAlignment="Top" Margin="2,8,-2,0" Grid.ColumnSpan="3" Height="28" Padding="3">
<ComboBoxItem>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*" MinWidth="105" />
<ColumnDefinition Width="60" />
</Grid.ColumnDefinitions>
<CheckBox IsChecked="true" VerticalAlignment="Center" Grid.Column="0"/>
<TextBlock Text="All" VerticalAlignment="Center" Grid.Column="1" Style="{x:Null}" FontSize="11"/>
</Grid>
</ComboBoxItem>
<ComboBoxItem>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*" MinWidth="105" />
<ColumnDefinition Width="60" />
</Grid.ColumnDefinitions>
<CheckBox IsChecked="true" VerticalAlignment="Center" Grid.Column="0"/>
<TextBlock Text="General" VerticalAlignment="Center" Grid.Column="1" Style="{x:Null}" FontSize="11"/>
<TextBox Text="25" VerticalAlignment="Center" Grid.Column="2" FontSize="11" Padding="2" HorizontalContentAlignment="Right"/>
</Grid>
</ComboBoxItem>
</ComboBox>
User have option to select multiple values
I am using MVVM pattern
Since all of your ComboBox Items are unchanging, you can give Names to those items and reference them directly.
<ComboBoxItem x:Name="ComboItemAll">
...
</ComboBoxItem>
<ComboBoxItem x:Name="ComboItemGeneral">
...
</ComboBoxItem>
and the in the Button Click event:
if (ComboItemAll.IsSelected)
{
...
}
else if (ComboItemGeneral.IsSelected)
{
...
}
alternatively, you could also get this information from your ComboBox "Type":
var selectedItem = Type.SelectedItem;
if (selectedItem.Name.StartsWith("ComboItemAll"))
{
...
}
else if (selectedItem.Name.StartsWith("ComboItemGeneral"))
{
...
}
For MVVM (Edit):
Xaml (View):
<ComboBox SelectedItem="{Binding SelectedCustomItem, Mode=TwoWay}" ItemsSource="{CustomItems}" ItemTemplate={StaticResource CustomItemsTemplate} />
Xaml (Resource):
<DataTemplate x:Key="CustomItemsTemplate">
<StackPanel
<CheckBox IsChecked="{Binding IsSelected}" VerticalAlignment="Center"/>
<TextBlock Text="{Binding CustomPropertyFromCustomClass}"/>
</StackPanel>
</DataTemplate>
VM:
public class ViewModel
{
public ViewModel()
{
CustomItems = new ObservableCollection<CustomClass>();
CustomItems.Add(new CustomClass() { "All" });
CustomItems.Add(new CustomClass() { "General" });
}
private ObservableCollection<CustomClass> customItems = null;
public ObservableCollection<CustomClass> CustomItems
{
get { return customItems; }
set
{
if (object.Equals(value, customItems) == false)
{
customItems = value;
OnPropertyChanged(() => CustomItems);
}
}
}
private CustomClass selectedCustomItem = null;
public CustomClass SelectedCustomItem
{
get { return selectedCustomItem; }
set
{
if (object.Equals(value, selectedCustomItem) == false)
{
selectedCustomItem= value;
OnPropertyChanged(() => SelectedCustomItem);
}
}
}
}
You should never reference your combobox directly from the ViewModel. Everything in your ViewModel should be related to data manipulation and know nothing of the View (aka ComboBox).
Everything else should be done in the view. If you need to access the ComboBox, you need you ask yourself why, and can I do that logic in the XAML through templates and bindings?