I have a ListBox which contains a couple of TextBlocks, an Image, and at least 2 TextBoxs. However my problem is that I need to be able to retrieve all the TextBox(s) in the ListBox; APART FROM THE FIRST ONE, and then assign them to a List in C#.
Here is the ListBox in .xaml:
<ListBox Margin="0,-20,0,0" Height="548" Name="listBoxNew">
<TextBlock Name="textBlockName" Text="Name"/>
<TextBox Name="textBoxName" Width="420" Margin="-12,0,0,0"/>
<TextBlock Name="textBlockAdd" Text="Add" Margin="0,10,0,0"/>
<TextBox Name="textBoxAdd" Width="420" Margin="-12,0,0,0"/>
<Image Name="imageAdd" Source="/SecondApp%2b;component/Images/buttonAdd1.png"
Height="50" Margin="0,5,0,0" Tap="imageAdd_Tap"
toolkit:TiltEffect.IsTiltEnabled="True"
ManipulationStarted="imageAddExersize_ManipulationStarted"
ManipulationCompleted="imageAddExersize_ManipulationCompleted" />
</ListBox>
The ListBox may have more TextBoxs than shown in .xaml, as the user can create more by tapping on the Image.
Thank alot, all help is appreciated.
You can do it very simply using Linq. Following sentence returns all the elements from the ListBox of type TextBox except the first one:
var textBoxList = listBoxNew.Items.Where(x => x.GetType() == typeof(TextBox)).Skip(1).ToList();
Remember you have to add using System.Linq; to your file.
hello #Newbie i have solution for you..i know it is not optimized one..but it is working for your case..
i am comparing the types..here ( by not good way) ..i ma doing on a buttonclick..
List<object> lstobj;
private void Button_Click_2(object sender, RoutedEventArgs e)
{
int t = listBoxNew.Items.Count();
lstobj = new List<object>();
TextBox obj = new TextBox();
int p = 0;
for (int i = 0; i < t; i++)
{
if(listBoxNew.Items[i].GetType()==obj.GetType())
{
if (p == 0)
{
p = 1;
continue;
}
else
{
lstobj.Add(listBoxNew.Items[i]);
}
}
}
}
hope it helps you..
Related
I'm trying to use a ListBox to choose an entry and then display a picture belonging to this selected entry. But just at the beginning I got my first problem: filling the ListBox with binding is working, but if I click on one line in my running program, it doesn't select the line. I can just see the highlighted hover effect, but not select a line. Any ideas what my mistake could be?
This is my XAML:
<ListBox x:Name="entrySelection" ItemsSource="{Binding Path=entryItems}" HorizontalAlignment="Left" Height="335" Margin="428,349,0,0" VerticalAlignment="Top" Width="540" FontSize="24"/>
And in MainWindow.xaml.cs I'm filling the ListBox with entries:
private void fillEntrySelectionListBox()
{
//Fill listBox with entries for active user
DataContext = this;
entryItems = new ObservableCollection<ComboBoxItem>();
foreach (HistoryEntry h in activeUser.History)
{
var cbItem = new ComboBoxItem();
cbItem.Content = h.toString();
entryItems.Add(cbItem);
}
this.entrySelection.ItemsSource = entryItems;
labelEntrySelection.Text = "Einträge für: " + activeUser.Id;
//show image matching the selected entry
if (activeUser.History != null)
{
int index = entrySelection.SelectedIndex;
if (index != -1 && index < activeUser.History.Count)
{
this.entryImage.Source = activeUser.History[index].Image;
}
}
}
So I can see my ListBox correctly filled, but not select anything - so I can't go on with loading the picture matching the selected entry.
I'm still quite new to programming, so any help would be great :)
EDIT: If someone takes a look at this thread later: here's the - quite obvious -solution
XAML now looks like this
<ListBox x:Name="entrySelection" ItemsSource="{Binding Path=entryItems}" HorizontalAlignment="Left" Height="335" Margin="428,349,0,0" VerticalAlignment="Top" Width="540" FontFamily="Siemens sans" FontSize="24">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code behind to fill it:
//Fill listbox with entries for selected user
DataContext = this;
entryItems = new ObservableCollection<DataItem>();
foreach (HistoryEntry h in selectedUser.History)
{
var lbItem = new DataItem(h.toString());
entryItems.Add(lbItem);
}
this.entrySelection.ItemsSource = entryItems;
labelEntrySelection.Text = "Einträge für: " + selectedUser.Id;
And new Class DataItem:
class DataItem
{
private String text;
public DataItem(String s)
{
text = s;
}
public String Text
{
get
{
return text;
}
}
}
You are filling it with ComboBoxItem, which is not relevant to the ListBox, and also wrong by definition.
You need to have the ObservableCollection filled with data items.
Meaning, make a class that contains the data you want to store, and the ListBox will generate a ListBoxItem automatically per data item.
http://www.wpf-tutorial.com/list-controls/listbox-control/
I have two pages: the first is mainpage.xaml and the second is favoriteslist.xaml.
In mainpage.xaml I have a text block, which shows some dynamic text automatically.
And I have a button also on mainpage.xaml.
From which I want when I click on that button, text appears on text block should go to favorite list in favoriteslist.xaml page.
If text already favorite, which text appears on text block should be removed from favorite list on button click.
So finally I need help to implement this functionality textblock which shows dynamically already created but I only need to know how to develop add to favorite functionality.
Textblock:
<TextBlock x:Name="StringTextBlock" Text="" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" />
Button:
<Button Grid.Row="2" x:Name="AddToFavoritesButton"
Content="Add" Style="{StaticResource ButtonStyle2}" Margin="2"
Click="AddToFavoritesButton_Click"/>
C#
private void AddToFavoritesButton_Click(object sender, RoutedEventArgs e)
{
}
Listbox:
<ListBox x:Name="FavoriteListBox" />
I would use IsolatedStorageSettings to store the list and compare the dynamic text to the list in the isolatedstoragesettings upon button click. Then on FavouritesList page, set itemsource of the listbox to the list in IsolatedStorageSettings.So here are the steps to be followed:
1. Create a model/class to set the dynamic text being shown on the text block
public class favourites
{
public string myText { get; set; }
}
2. In the button click event on MainPage.xaml.cs, first set the dynamic text (where ever you are getting it from) to the text block if you need to and then create the list and/or compare
private void AddToFavoritesButton_Click(object sender, RoutedEventArgs e)
{
//your dynamic text set to textblock
StringTextBlock.Text = myDynamicText;
//Set value of your text to member variable of the model/class
favourites f = new favourites();
f.myText = myDynamicText;
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
/*Check if "FavouritesList" key is present in IsolatedStorageSettings
which means already a list had been added. If yes, retrieve the
list, compare each item with your dynamic text, add or remove
accordingly and replace the new list in IsolatedStorageSettings
with same key. */
if (settings.Contains("FavouritesList"))
{
List<favourites> l = (List<favourites>)settings["FavouritesList"];
for(int i = 0; i <= l.Count()-1; i++)
{
if (l[i].Equals(myDynamicText))
{
l.RemoveAt(i);
settings["FavouritesList"] = l;
}
else
{
l.Add(f);
settings["FavouritesList"] = l;
}
}
}
//If no key in IsolatedStorageSettings means no data has been added
//in list and IsolatedStorageSettings. So add new data
else
{
List<favourites> l = new List<favourites>();
l.Add(f);
settings["FavouritesList"] = l;
}
settings.Save();
}
Now all that is left is show the always updated list in the FavouritesList Page. I added a 'NoData' textblock that should be visible when there is nothing in the list. Else the list will be displayed.
In FavouritesList.xaml
<ListBox x:Name="FavoriteListBox" Visibility="Collapsed">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding myText}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Name="NoData"
Text="No Data"
Visibility="Collapsed"
Width="50"
Height="50"/>
In FavouritesList.xaml.cs
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
if (settings.Contains("FavouritesList"))
{
List<favourites> l = (List<favourites>)settings["FavouritesList"];
if(l.Count!= 0)
{
NoData.Visibility = System.Windows.Visibility.Collapsed;
FavoriteListBox.Visibility = System.Windows.Visibility.Visible;
FavoriteListBox.ItemsSource = l;
}
}
else
{
FavoriteListBox.Visibility = System.Windows.Visibility.Collapsed;
NoData.Visibility = System.Windows.Visibility.Visible;
}
I have not tested this but should definitely work. Hope it helps!
I am trying to update the list which is Bound to ListBox , When the scroll bar reaches end.I need to update the list and show the changes in UI also.Here it is not updating automatically.Can someone please help me in fulfilling my requirement.
If i tried to use TwoWay mode, It shows below error:
Error : Invalid binding path 'itemsList' : Cannot bind type 'System.Collections.Generic.List(System.String)' to 'System.Object' without a converter
<ScrollViewer
x:Name="sv"
ViewChanged="OnScrollViewerViewChanged">
<ListBox x:Name="listView"
HorizontalAlignment="Left"
Height="Auto"
VerticalAlignment="Top"
Width="172"
ItemsSource="{x:Bind itemsList, Mode=OneWay}"/>
</ScrollViewer>
and the code
public List<String> itemsList = new List<string>();
private void OnScrollViewerViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
var verticalOffset = sv.VerticalOffset;
var maxVerticalOffset = sv.ScrollableHeight; //sv.ExtentHeight - sv.ViewportHeight;
if (maxVerticalOffset < 0 ||
verticalOffset == maxVerticalOffset)
{
// Scrolled to bottom
Util.debugLog("REACHED BOTTOM");
int i;
// itemsList = null;
itemsList.Clear();
for (i = 0; i < 20; i++)
{
itemsList.Add("Item number " + i + 900);
}
}
else
{
// Not scrolled to bottom
// rect.Fill = new SolidColorBrush(Colors.Yellow);
}
}
Here(In below link) is the answer for my question.Thanks alot for all who tried to answer my question.
https://social.technet.microsoft.com/Forums/en-US/7c730558-f933-4483-8d5b-1710d19f99de/xbind-in-windows-10-mode-one-way-i-am-trying-to-update-the-bind-list-when-scrollview-reached-to?forum=wpf
i am currently trying to remove items from a bound list.
Here is where it is bound in the xaml.
<ListBox Height="362" HorizontalAlignment="Left" Margin="6,245,0,0" Name="lstHoldCategories" VerticalAlignment="Top" Width="462" SelectionChanged="list_SelectionChanged_1" BorderThickness="0,0,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<!--This positions the Text eg name etc-->
<StackPanel Orientation ="Vertical">
<!--This changes the size of the photo on the left-->
<Image Width="445" Height="300" HorizontalAlignment="Center" Stretch="UniformToFill" >
<Image.Source>
<BitmapImage UriSource="{Binding imgSource}"/>
</Image.Source>
</Image>
<TextBlock Text="{Binding Name}" Style="{StaticResource PhoneTextLargeStyle}" Width="1000" />
<TextBlock Text="{Binding Type}" Style="{StaticResource PhoneTextLargeStyle}" Width="1000" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I have then made a seperate generic list to be held in a seperate unbound listBox so that i can select a "Type" and load up all the animals of that type.
Here is the code where i set up the unbound list
public CategorySearch()
{
InitializeComponent();
observablePets = new ObservableCollection<Shop>();
temp = new ObservableCollection<Shop>();
MyList.Add("Dog");
MyList.Add("Cat");
MyList.Add("Fish");
MyList.Add("Lizard");
lstCategory.ItemsSource = MyList;
}
and this is where i have done the SelectedIndex of the unbound listBox to add in the animals of the selected "Type"
private void lstCategory_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (lstCategory.SelectedIndex == 0)
{
foreach (Shop pet in thisApp.myshop)
{
if (pet.Type == "Dog")
{
//lstHoldCategories.Items.Clear();
temp.Add(pet);
lstHoldCategories.ItemsSource = temp;
}
}
}
if (lstCategory.SelectedIndex == 1)
{
foreach (Shop pet in thisApp.myshop)
{
if (pet.Type == "Cat")
{
//lstHoldCategories.Items.Clear();
temp.Add(pet);
lstHoldCategories.ItemsSource = temp;
}
}
}
if (lstCategory.SelectedIndex == 2)
{
foreach (Shop pet in thisApp.myshop)
{
if (pet.Type == "Fish")
{
//lstHoldCategories.Items.Clear();
temp.Add(pet);
lstHoldCategories.ItemsSource = temp;
}
}
}
if (lstCategory.SelectedIndex == 3)
{
foreach (Shop pet in thisApp.myshop)
{
if (pet.Type == "Lizard")
{
//lstHoldCategories.Items.Clear();
temp.Add(pet);
lstHoldCategories.ItemsSource = temp;
}
}
}
}
As you can see in this piece of code, I have commented out the piece of code that i believed would empty the listBox on the selectedIndex and reload the listBox with the new selection. Unfortunately it doesn't work and crashes the app when you select an index.
If there is a different way to empty the listBox that is bound, i would appreciate someone advising me how to do it,
Thanks in advance,
Jason
////Pics\\
This is what the page looks like before an index is selected
This is what the bound listBox will look like when you select an index
You need to clear the collection itself, rather than the object bound to the collection. A quick search showed up this... Delete all items from listobox
Just to clarify, the Items collection lives on the ListBox and that property is readonly. So you need to remove the items from the collection your ListBox is actually bound to.
you should just be able to call clear on temp prior to adding you new items. But you will need to make sure your collection source implements the INotifyCollectionChanged to see the changes reflected in the UI.
I have a listbox with a data template bound to a list<class> in the program.
<DataTemplate x:Key="pTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Ref}" Padding="5,0,0,0"/>
<StackPanel Name="taggedA" Tag="{Binding A}" Orientation="Horizontal">
<TextBlock Name="selectedA" Text="{B}" />
</StackPanel>
<Image Name="ind" Width="40" Height="40" />
</StackPanel>
</DataTemplate>
On button click, I want to go over all the elments of the listbox and check if the stackPanel taggedA's tag == textblock selectedA's text.
This is to be done for each of the items in the list box and the data template is as above. How can this be done?
Easier to compare the binding source directly:
ListBox l = myListBox;
for (int i = 0; i < l.Items.Count; i++)
{
var boundObject = (MyClass)l.Items[i];
MessageBox.Show("They are equal? " + (boundObject.A == boundObject.B));
}
I would agree with #dbaseman. But if you are set on doing it you could do the following:
private void button_click(object sender, RoutedEvent e)
{
foreach(var item in MyListBox.Items)
{
ListBoxItem lbi = MyListBox.ItemContainerGenerator.ContainerFromItem(item);
StackPanel taggedApanel = (lbi.Content as StackPanel).Children[1];
//Do whatever you need to do here
}
}