I have a ListView that is enclosed inside a dragablz tabs plugin:
<dragablz:TabablzControl Opacity="0.8" BorderBrush="#FF4C589C" Margin="10,49,10,10" Background="#FF402D61" TabStripPlacement="Left">
<dragablz:TabablzControl.InterTabController>
<dragablz:InterTabController />
</dragablz:TabablzControl.InterTabController>
<TabItem Header="Texts">
<WrapPanel x:Name="textContainer"/>
</TabItem>
<TabItem Header="Files">
<ListView SelectionMode="Extended" x:Name="files" Background="#FF19174B" AllowDrop="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled" PreviewMouseLeftButtonDown="files_PreviewMouseLeftButtonDown" MouseMove="files_MouseMove">
<ListView.DataContext>
<local:FileItem/>
</ListView.DataContext>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<local:FileItem/>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</TabItem>
</dragablz:TabablzControl>
The caller window calls InitItems() method of the window containing this ListView populating it with user controls of type FileItem:
public int InitItems()
{
FileOps.UserDataCollection userData = Utility.userData;
if (userData != null && userData.userData != null && userData.userData.Count > 0)
{
foreach (UserData ud in userData.userData)
{
switch (ud.DataType)
{
case "file": _FileItems.Add(new FileItem(ud));
break;
default: break;
}
}
files.ItemsSource = FileItems;
}
return 0;
}
FileItems and _FileItems are defined as:
private ObservableCollection<FileItem> _FileItems = new ObservableCollection<FileItem>();
public ObservableCollection<FileItem> FileItems
{
get
{
return _FileItems;
}
}
Which are getting data successfully when checked using a breakpoint on line files.ItemsSource = FileItems; in InitItems() method.
But the problem is that the ListView is not showing the user controls. Please tell me what I am missing? I am just a beginner in WPF.
Related
I have a listBox that already populated by MySql table. I want to change the content of listBox anyway user pressing a button, what I done for this is to call sql class creator in my code with new query that filter the data from table, the problem is how to change listbox content in that button event handler?
here is my codes
private void shirtSelect_Click(object sender, RoutedEventArgs e)
{
string shirt = "SELECT * FROM viewermenu.grament where type = 'shirt'";
var shirtTable = new DatabaseTable();
string id = null;
shirtTable.GetTable(shirt, id);
listBox.DataContext = shirtTable;
}
and xaml side:
<ListBox x:Name="listBox" BorderBrush="Transparent" Background="Transparent" SelectionChanged="listBox_SelectionChanged" SelectionMode="Single" ItemsSource="{Binding Source={StaticResource NamesTable}}" it HorizontalContentAlignment="Center" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" RenderTransformOrigin="0.5,0.5" Margin="0" Padding="0,0,0,317" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="200" Width="200" >
<Image Margin="3" Source="{Binding pic_path}" RenderOptions.BitmapScalingMode="HighQuality" RenderOptions.EdgeMode="Aliased"/>
<TextBox Margin="3" Text="{Binding name}" Visibility="Visible"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and databbase table class:
public DataTable GetTable(String query, String sortBy)
{
String connString = "server=192.168.*.**;uid=*****;pwd=****;database=viewermenu";
connection = new MySqlConnection(connString);
adapter = new MySqlDataAdapter(query, connection);
DataTable dataTable = new DataTable();
adapter.Fill(dataTable);
dataTable.DefaultView.Sort = sortBy;
return dataTable;
}
}
Some mistakes in the given code, correct them and have a try.
1.Add IsItemsHost to the ItemsPanelTemplate:
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
2.Define a ShirtData class:
public class ShirtData
{
public string pic_path { get; set; }
public string name { get; set; }
public ShirtData(string path, string theName)
{
pic_path = path;
name = theName;
}
}
3.Set the ItemsSource in the code-behind (some pseudocode):
.......
var table = shirtTable.GetTable(shirt, id);
var shirts = new List<ShirtData>();
foreach (DataRow row in table.Rows)
{
var shirtData = new ShirtData(row["pic_path"].ToString(), row["name"].ToString());
shirts.Add(shirtData);
}
listBox.ItemsSource = shirts;
You need to amend the property that is bound to NamesTable below.
ItemsSource="{Binding Source={StaticResource NamesTable}}"
ie, assuming the property is a list, add and remove items as you would normally do with a list.
I have the following nested ListViews:
<!-- Display a list of each CustomTab -->
<!-- Drag & Drop functionality implemented in code behind using ListViewDragDropManager -->
<ListView Name="TasksListView"
ItemsSource="{Binding Model.TaskCollection, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
BorderThickness="0">
<ListView.ItemTemplate>
<DataTemplate>
.....
<!-- Parameters List -->
<ListView Name="TaskParameterListView"
ItemsSource="{Binding TaskParameterCollection, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
BorderThickness="0">
<ListView.ItemTemplate>
<DataTemplate>
.....
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I need to get access to the TaskParameterListView in code behind. How can I get a reference to this object?
With the TasksListView I can access it simply by calling this.TasksListView
Here is how you can find inner ListView using FrameworkTemplate.FindName:
DependencyObject container = TasksListView
.ItemContainerGenerator
.ContainerFromItem(TasksListView.SelectedItem);
if (container != null)
{
ContentPresenter presenter = GetPresenter(container);
ListView listView = presenter
.ContentTemplate
.FindName("TaskParameterListView", presenter) as ListView;
}
Additional method to find a ContentPresenter inside the ListBoxItem:
private static ContentPresenter GetPresenter(DependencyObject reference)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(reference); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(reference, i);
ContentPresenter presenter =
child as ContentPresenter ??
GetPresenter(child);
if (presenter != null)
{ return presenter; }
}
return null;
}
<ListBox x:Name="my_list" Grid.Row="0" Margin="0,34,0,10">
<ItemsControl.ItemTemplate >
<DataTemplate >
<StackPanel Orientation="Horizontal" >
<CheckBox x:Name="cbx_state" Tag="{Binding}" Checked="cbx_state_Checked" Unchecked="cbx_state_Unchecked" />
<StackPanel Orientation="Vertical">
<TextBlock x:Name="txt_string" Text="{Binding}" VerticalAlignment="Center" FontSize="34" />
<TextBlock x:Name="txt_string1" Text=" Text " VerticalAlignment="Center" FontSize="20" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
I have binded the listbox with a list containing items more then 10.What i did is on application bar menu item click i wanted to check all the checkbox .But this method i have implemented have different behavior.Sometimes the child count is returned less then the actual count.Method is :
private void GetItemsRecursive(DependencyObject lb)
{
var childrenCount = VisualTreeHelper.GetChildrenCount(lb);
for (int i = 0; i < childrenCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(lb, i);
if (child is CheckBox)
{
CheckBox targeted_element = (CheckBox)child;
targeted_element.IsChecked = true;
if (targeted_element.IsChecked == true)
{
return;
}
}
GetItemsRecursive(child);
}
}
I am getting childrenCount as different value every time and therefore resulting in leaving some check boxes as unchecked.
The ListBox uses a virtualizing container. What that means is that the items are loaded only when they're needed (more or less just before showing on the screen).
What you can to is change the default Listbox.ItemsPanel to StackPanel
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
However, that might hurt the performance of your app, especially in the case of long lists. You're already using bindings for your checkboxes. The best solution would be to rely on MVVM - add a Checked-binding and instead of calling GetItemsRecursive execute a command on the ViewModel that sets the List-ViewModel checked property.
I have a listBox1 in which data are binding from the list. Then I want to when I select any item from listBox1 in listBox2 will binding data from another list.
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Teams teams = (Teams)listBox1.SelectedItems[0];
getH2hResults("//td[#class='hell']", teams.Team1, teams.Team2); // add elements to list
getH2hResults("//td[#class='dunkel']", teams.Team1, teams.Team2); // and here also
listBox2.ItemsSource = lists.h2hList;
}
On the first time this work, but for the twice time listBox2 doesn't displays new data.
public class Lists : BindableBase
{
public Lists()
{
_teamsList = new List<Teams>();
_h2hList = new List<H2H>();
}
private List<Teams> _teamsList;
public List<Teams> teamsList
{
get
{
return _teamsList;
}
set
{
if (value != _teamsList)
{
_teamsList = value;
RaisePropertyChanged("teamsList");
}
}
}
private List<H2H> _h2hList;
public List<H2H> h2hList
{
get
{
return _h2hList;
}
set
{
if (value != _h2hList)
{
_h2hList = value;
RaisePropertyChanged("h2hList");
}
}
}
}
And XAML
<ListBox Name="listBox1" Width="300" Height="300"
VerticalAlignment="Top"
HorizontalAlignment="Left"
ItemsSource="{Binding teamsList}" SelectionChanged="listBox1_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="#FF4273CD" Text="{Binding Team1, Mode=TwoWay}"></TextBlock>
<TextBlock Text=" vs " FontWeight="Bold"></TextBlock>
<TextBlock Foreground="#FF4273CD" Text="{Binding Team2, Mode=TwoWay}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Name="listBox2" Grid.Column="1" Width="300" Height="300"
VerticalAlignment="Top"
HorizontalAlignment="Left"
ItemsSource="{Binding h2hList}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding date, Mode=TwoWay}"></TextBlock>
<TextBlock Text="{Binding result, Mode=TwoWay}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
RaisePropertyChanged("teamList");
is Wrong your propery is named 'teamsList' with an S,
change to:
RaisePropertyChanged("teamsList");
It is the public property you bind to and notify changes of,
edit:
also change your binding:
ItemsSource="{Binding teamList}"
to
ItemsSource="{Binding teamsList}"
Edit 2:
listBox2.DataContext = xxx
Not itemsource = xxx
With the line (in listBox1_SelectionChanged)
listBox2.ItemsSource = lists.h2hList;
you are effectively removing the binding from the ItemsSource property of listBox2.
Instead, you should only update the h2hList property in your Lists class (which presumably happens in getH2hResults) and remove the above line from your code.
Note however that it is not sufficient to clear and re-fill that list. You need to set the h2hList property in order to get a property change notification raised:
var newList = new List<H2H>();
// fill newList before assigning to h2hList property
lists.h2hList = newList;
If you want to keep the list and just change its elements, you would need to use ObservableCollection<H2H> instead of List<H2H> as collection type. This would be the better approach anyway, as you would not have to care for when exactly you add elements to a newly created collection.
I have a Datatemplete for List-box Item in which I have a Grid with two columns using WPF. In the first column I want to put few customized controls(Buttons) dynamically using C# in code behind. I don't know how to start and from where should I start, can anybody please help me with some great inputs and examples. Any answer will be greatly appreciate.
Thanks in advance.
XAML code:
<ListBox x:Name="ListBoxItem"
Grid.Row="1"
SelectionMode="Extended"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
FocusVisualStyle="{x:Null}"
KeyboardNavigation.IsTabStop="False"
Background="DarkGray"
ItemsSource="{Binding}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel x:Name="ListContent"
IsItemsHost="True"
Width="500"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel LastChildFill="True"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<StackPanel DockPanel.Dock="Left"
Width="30"
Height="{Binding Height}">
<--Here I want to put few customize buttons in code behind-->
</StackPanel>
<Image x:Name="MainPage"
Stretch="UniformToFill"
Source="{Binding ImagePath}"
Height="{Binding Height}"
Width="{Binding Width}"/>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
You specified wanting to use code behind, so it would look something like this:
XAML:
<StackPanel Initialized="StackPanel_Initialized" .. />
Code behind:
using MyNamespace;
private void StackPanel_Initialized(object sender, EventArgs e)
{
MyControl newItem = new MyControl();
// Set any other properties
StackPanel parent = sender as StackPanel;
parent.Children.Add(newItem);
}
If you are looking for adding Controls inside a the First column of your grid then put a Panel inside the first column and in code behind add controls as child to that Panel. So as you mentioned in above that you are using DataTemplete then I would like to say that you can access that Panel something like:
Put the below codes inside the event where you wnt to add the controls.
ListBoxItem item = (ListBoxItem)(this.lst.ItemContainerGenerator.ContainerFromIndex(i));
ContentPresenter presenter = FindVisualChild<ContentPresenter>(item);
DataTemplate template = presenter.ContentTemplate;
StackPanel stack = (StackPanel)template.FindName("FirstColumn Panel Name", presenter);
and then call the below method:
private childItem FindVisualChild<childItem>(DependencyObject obj)
where childItem : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is childItem)
return (childItem)child;
else
{
childItem childOfChild = FindVisualChild<childItem>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}