How do I Random all the items in the listbox? - c#

I don't want to random number, I want to random all the items in the listbox in C# XAML Windows Store App??
Anyone have code for that or have any idea how to do that?
I have this code of listbox
<ListBox Name="Playlist" Background="White" DoubleTapped="Playlist_DoubleTapped" KeyUp="Playlist_KeyUp"
Foreground="Black" SelectionMode="Single" SelectionChanged="Playlist_SelectionChanged"
ScrollViewer.VerticalScrollMode="Enabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Grid.Column="0" Margin="28,82,1067,32">
#Baldrick this is how i am adding songs/videos to the playlist listbox
public async void OpenFileButton_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.ViewMode = PickerViewMode.List;
filePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary;
filePicker.CommitButtonText = "Play";
foreach (string fileExtension in supportedAudioFormats)
{
filePicker.FileTypeFilter.Add(fileExtension);
}
foreach (string fileExtension in supportedVideoFormats)
{
filePicker.FileTypeFilter.Add(fileExtension);
}
IReadOnlyList<StorageFile> selectedFiles = await filePicker.PickMultipleFilesAsync();
if (selectedFiles.Count > 0)
{
foreach (StorageFile file in selectedFiles)
{
Playlist.Items.Add(file);
}
systemMediaControls.IsEnabled = true;
mediaSource.AutoPlay = true;
await SetNewMediaItem(0); // Start with first file in the list of picked files.
StorageFile files = Playlist.SelectedItem as StorageFile;
Thumbnail(files);
}
}

Here is an example.
XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" Name="Playlist" ItemsSource="{Binding Path=PlaylistItems}"/>
<Button Grid.Row="1" Name="Shuffle" Content="Shuffle" Click="Shuffle_Click"/>
</Grid>
Note that there is PlaylistItems binded to ListBox. It would be the best to manipulate the collection of items, which is binded to ListBox, instead of manipulating ListBox itself.
C# code:
First you should define that PlaylistItems collection.
public ObservableCollection<string> PlaylistItems
{
get;
set;
}
And to make it possible to bind it to the ListBox, it is necessary to set the DataContext of your control (window or whatever).
public MainWindow()
{
InitializeComponent();
this.DataContext = this; // <--
}
Now let's initialize PlaylistItems collection and add few items.
public void InitializeItems(int count)
{
var items = new List<string>(count);
for (int i = 0; i < count; i++)
items.Add("Item " + i);
PlaylistItems = new ObservableCollection<string>(items);
}
You can call this method in the constructor.
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
InitializePlaylist(10); // <--
}
And finally shuffle functionality.
public IEnumerable<string> ShuffleItems(IEnumerable<string> items)
{
var rnd = new Random();
return items.OrderBy(item => rnd.Next()).ToList();
}
Use it in your button handler to repopulate PlaylistItems with randomized items.
private void Shuffle_Click(object sender, RoutedEventArgs e)
{
var shuffledItems = ShuffleItems(PlaylistItems);
PlaylistItems.Clear();
foreach (var item in shuffledItems)
PlaylistItems.Add(item);
}

Related

C# UWP Listview/GridView mark of selected item

I am creating UWP app, and I maked external arrow "marker" of selected item in listview...
Like this:
I have managed to achieve this with next code:
var current = lvMain.Items.FirstOrDefault(a => (a as MyModel).Selected) as MyModel;
ListViewItem selected = lvMain.ContainerFromItem(current) as ListViewItem;
GeneralTransform generalTransform1 = gvEpg.TransformToVisual(selected);
Point currentPoint = generalTransform1.TransformPoint(new Point());
In Scroll change event I am calling this and set the arrow position by the Point of my item. And this is working.
But, I want to simplified this. Is there any kind of binding or something like that, that would make arrow always follow the item?
Here's the sample.
XAML MainPage:
<Page.Resources>
<DataTemplate x:Key="DataTemplate">
<Canvas Height="80" Width="200">
<TextBlock Text="{Binding}"/>
</Canvas>
</DataTemplate>
</Page.Resources>
<StackPanel Orientation="Horizontal">
<ListView x:Name="ListView" Width="400"
SelectionChanged="ListView_OnSelectionChanged"
ItemTemplate="{StaticResource DataTemplate}"/>
<Canvas x:Name="ParentCanvas">
<Image x:Name="Arrow"
Stretch="UniformToFill" Width="200" Height="80"
Source="Assets/Red_Left_Arrow.png"/>
</Canvas>
</StackPanel>
Code behind:
private readonly List<string> _names = new List<string>();
private Visual _rectangleVisual;
private Visual _parentVisual;
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 32; i++)
{
_names.Add("item " + i);
}
ListView.ItemsSource = _names;
_parentVisual = ElementCompositionPreview.GetElementVisual(ParentCanvas);
_rectangleVisual = ElementCompositionPreview.GetElementVisual(Arrow);
var border = VisualTreeHelper.GetChild(ListView, 0) as Border;
var scrollViewer = border.Child as ScrollViewer;
var scrollerProperties = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(scrollViewer);
var offsetExpressionAnimation = _rectangleVisual.Compositor.CreateExpressionAnimation("Scroller.Translation.Y");
offsetExpressionAnimation.SetReferenceParameter("Scroller", scrollerProperties);
_rectangleVisual.StartAnimation("Offset.Y", offsetExpressionAnimation);
}
private void ListView_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listViewItem = ListView.ContainerFromItem(ListView.SelectedItem) as ListViewItem;
var listItemVisual = ElementCompositionPreview.GetElementVisual(listViewItem);
_parentVisual.Offset = new Vector3(_parentVisual.Offset.X, listItemVisual.Offset.Y, 0);
}
Looks like what you asked for:

Stringbuilder Append save file, List<string>

EDIT:
Program: I have a list of car model names and beside them numbers from 1 to 4, the user gets to input the number in the Textbox of the car he/she wants to save. The number correlates to the name of the car and saves it in the stringbuilder append.
Problem: How do I save the words that are put in the Textbox in a Stringbuilder Append? Also can I create another textbox and save other words threw the same Stringbuilder?
public partial class MainWindow : Window
{
ObservableCollection<string> Items = new ObservableCollection<string>();
StringBuilder sb = new StringBuilder();
public MainWindow()
{
InitializeComponent();
Items.Add("1.Honda");
Items.Add("2.Toyota");
Items.Add("3.Fiat");
Items.Add("4.Ferrari");
}
private void SaveFile_Click(object sender, RoutedEventArgs e)
{
if (txtValue.Text == "1"){txtValue.Text = "Honda";}
if (txtValue.Text == "2") { txtValue.Text = "Toyota"; }
if (txtValue.Text == "3") { txtValue.Text = "Fiat"; }
if (txtValue.Text == "4") { txtValue.Text = "Ferrari"; }
foreach (string txtValue in Items) //Just playing around trying to figure out how to Append
{
sb.Append(Items).AppendLine();
}
SaveFileDialog saveFileDialog = new SaveFileDialog();
if (saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
File.WriteAllText(saveFileDialog.FileName, txtValue.Text);
}
}
}
XAML
<Window.Resources>
<x:Array x:Key="Items" Type="{x:Type sys:String}"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String>1.Honda</sys:String>
<sys:String>2.Toyota</sys:String>
<sys:String>3.Fiat</sys:String>
<sys:String>4.Ferrari</sys:String>
</x:Array>
</Window.Resources>
<Grid>
<StackPanel Margin="10">
<TextBox x:Name="txtValue" />
<ListBox Height=" 100" ItemsSource="{StaticResource Items}" >
</ListBox>
<Button Name="SaveFile" Click="SaveFile_Click" >OK</Button>
</StackPanel>
</Grid>
</Window>

Get selected row item in DataGrid WPF doesn't work

Im tring to get Selected row item.
I have been readed that it should be worked :
<DataGrid ItemsSource="{Binding Path=Customers}"
SelectedItem="{Binding Path=SelectedCustomer, Mode=TwoWay}"/>
Customer customer = (Customer)myDataGrid.SelectedItem;
In the first xaml - I put it, it doesnt error or something I just dont know how to use it.. How in the c# code I can get the selected row ?
In the C# line code It error. The visual studio doesn't exist Customer.
I would thankfull to help. :) Thanks.
rly hard to know what exactly you wanted :) but here is an example I just put togetter on how to drag info out of the datagrid.
Did not implament alot of those bindings in it so this is pure getting the info.
Xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0" Name="dg"/>
<Button Grid.Row="1" Name="btn" Click="btn_Click" />
</Grid>
Codebehind
List<SomeInfo> list = new List<SomeInfo>();
public MainWindow()
{
InitializeComponent();
list.Add(new SomeInfo() { Name = "PC", Description = "Computer", ID = 1 });
list.Add(new SomeInfo() { Name = "PS", Description = "Playstation", ID = 2 });
list.Add(new SomeInfo() { Name = "XB", Description = "Xbox", ID = 3 });
this.dg.ItemsSource = list;
}
public class SomeInfo
{
public string Name { get; set; }
public string Description { get; set; }
public int ID { get; set; }
}
private void btn_Click(object sender, RoutedEventArgs e)
{
if (dg.SelectedIndex != -1)
{
DataGrid dataGrid = sender as DataGrid;
DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(dg.SelectedIndex);
DataGridCell RowColumn = dg.Columns[0].GetCellContent(row).Parent as DataGridCell;
btn.Content = ((TextBlock)RowColumn.Content).Text;
}
}
the btn_click does all the gathering info stuff where the last 2 makes my datagrid for testing.
Hope it will help you out :)
------------------Edit--------------------------
from the comment this below is what you would need only
private void btn_Click(object sender, RoutedEventArgs e)
{
if (dg.SelectedIndex != -1)
{
DataGrid dataGrid = sender as DataGrid;
DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(dg.SelectedIndex);
DataGridCell RowColumn = dg.Columns[0].GetCellContent(row).Parent as DataGridCell;
btn.Content = ((TextBlock)RowColumn.Content).Text;
}
}
dg = your datagrid
dg.Columns[0] = change 0 into what column you want
info from btn.Content = what you want the content to be
--------------EDIT 2------------
To get the selected row's index all you need is
int index = dg.SelectedIndex;
btn.Content = index;
or if you dont want to store the integar
btn.Content = dg.SelectedIndex;
The grid defined in a very incomplete.
Council to explicitly all columns that compose it with the individual binding
In this case I used the event doubleClick but you have to choose the right event to you
By code for example try this:
In XAML add:
<DataGrid x:Name="MyDataGrid" x:FieldModifier="public" MouseDoubleClick="MyDataGrid_MouseDoubleClick" ItemsSource="{Binding Path=Customers}"
SelectedItem="{Binding Path=SelectedCustomer, Mode=TwoWay}"/>
And in behind c# code this:
private void MyDataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (sender != null)
{
DataGrid grid = sender as DataGrid;
if (grid != null && grid.SelectedItems != null && grid.SelectedItems.Count == 1)
{
var selectedRow = grid.SelectedItem as MyObject;
try
{
Mouse.OverrideCursor = Cursors.Wait;
//TODO YOUR OPERATION ON selectdRow
}
finally
{
Mouse.OverrideCursor = null;
}
}
}
}

Windows phone LonglistSelector not rendering all items

I'm struggling with a longlistselector and item realized event. The problem I'm facing is that the longlistselector does not show all elements.
The code I'm doing is not using MVVM (I know that I should use, but in this scenario I can't...it was heritage code).
This is what I have:
XAML:
<Scrollviewer>
<stackpanel>
<phone:LongListSelector Margin="0,15,0,0" ScrollViewer.VerticalScrollBarVisibility="Visible" x:Name="LBhistory" LayoutMode="List"
BorderThickness="0,15,0,0" >
<phone:LongListSelector Margin="0,15,0,0" ScrollViewer.VerticalScrollBarVisibility="Visible" x:Name="LBDevices" LayoutMode="List" BorderThickness="0,15,0,0" >
<phone:LongListSelector Margin="0,15,0,0" ScrollViewer.VerticalScrollBarVisibility="Visible" x:Name="LBfiles" LayoutMode="List" BorderThickness="0,15,0,0" >
</stackpanel>
</ScrollViewer>
CS file:
private bool _isLoadingAllFile;
private int _pageNumber = 0;
private ObservableCollection<PhotoObject> allFiles = new ObservableCollection<PhotoObject>();
public BackupPivotPage()
{
....
this.Loaded += PivotPage_Loaded;
}
private void PivotPage_Loaded(object sender, RoutedEventArgs e)
{
LBfiles.ItemsSource = allFiles;
LBfiles.ItemRealized += LBfiles_ItemRealized;
searchImages(_pageNumber++);
}
private void searchImages(int p)
{
_isLoadingAllFile = true;
var x = dbAllFiles.Skip(p * GlobalSettings.PageSize.myPictures)
.Take(GlobalSettings.PageSize.myPictures);
foreach (var toAddObject in x)
{
this.allFiles.Add(toAddObject);
}
_isLoadingAllFile = false;
}
void LBfiles_ItemRealized(object sender, ItemRealizationEventArgs e)
{
try
{
if (!_isLoadingAllFile && LBfiles.ItemsSource != null &&
LBfiles.ItemsSource.Count >= Constants.offsetKnob)
{
if (e.ItemKind == LongListSelectorItemKind.Item)
{
if ((e.Container.Content as PhotoObject)
.Equals(LBfiles.ItemsSource[LBfiles.ItemsSource.Count - Constants.offsetKnob]))
{
searchImages(this._pageNumber++);
}
}
}
}
catch (Exception e1)
{
}
}
Right now my problem is that I know that allFiles has 96 elements, but only 67 are shown and the rest appear as white...any idea why?
EDIT
I've update with the scrollviewer...because I've 3 longlistselectors in the same page...and only this last one doesn't show all the items.
The problem seems to be around the time with which the data is loaded (or the thread). The ItemRealised event happens on a Background Thread therefore isn't able to update the User interface. In the example reference below they perform a similar operation to yours but retrieve the data using Deployment.Current.Dispatcher. This is used to do the work on the UI thread.
Try something similar to the following:
Try
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
var x = dbAllFiles.Skip(p * GlobalSettings.PageSize.myPictures)
.Take(GlobalSettings.PageSize.myPictures);
foreach (var toAddObject in x)
{
this.allFiles.Add(toAddObject);
}
IsLoading = false;
});
}
catch (Exception e)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Network error occured " + e.Message);
});
}
TwitterSearch - Windows Phone 8 LongListSelector Infinite Scrolling Sample

sort and group Icollectionview in WPF

I have created a listview control in WPF and has success fully bound Icollectionview object of ObservableCollection<object>. My listview columns are created dynamically.
I have to sort and group my listview and it is not working properly.
My code is as below.
private void LaodList()
{
dt = new DataTable();
dt.Columns.Add("AA", typeof(string));
dt.Columns.Add("BB", typeof(string));
dt.Columns.Add("cc", typeof(string));
dt.Rows.Add("12", "66",11);
dt.Rows.Add("33", "44",22);
dt.AcceptChanges();
GridView gv = new GridView();
//gv.AllowsColumnReorder = true;
List<string> myItemsCollection = new List<string>();
for (int i = 0; i < dt.Columns.Count; i++)
{
GridViewColumn col = new GridViewColumn();
col.Header = dt.Columns[i].ColumnName;
col.DisplayMemberBinding = new Binding(string.Format("[{0}]", i));
gv.Columns.Add(col);
myItemsCollection.Add(col.Header.ToString());
}
LvItems.View = gv;
this.Source = CollectionViewSource.GetDefaultView(LoadItems(dt)) ;
LvItems.DataContext = this.Source;
cmbGroups.ItemsSource = myItemsCollection;
}
public ObservableCollection<object> LoadItems(DataTable dt)
{
ObservableCollection<object> items = new ObservableCollection<object>();
foreach (DataRow dataRow in dt.Rows)
{
items.Add(dataRow.ItemArray);
}
return items;
}
//sort////////////////////////
private void ListView_Click(object sender, RoutedEventArgs e)
{
GridViewColumnHeader currentHeader = e.OriginalSource as GridViewColumnHeader;
if (currentHeader != null && currentHeader.Role != GridViewColumnHeaderRole.Padding)
{
if (this.Source.SortDescriptions.Count((item) => item.PropertyName.Equals(currentHeader.Column.Header.ToString())) > 0)
{
SortDescription currentPropertySort = this.Source
.SortDescriptions
.First<SortDescription>(item => item.PropertyName.Equals(currentHeader.Column.Header.ToString()));
//Toggle sort direction.
ListSortDirection direction =
(currentPropertySort.Direction == ListSortDirection.Ascending) ?
ListSortDirection.Descending : ListSortDirection.Ascending;
//Remove existing sort
this.Source.SortDescriptions.Remove(currentPropertySort);
this.Source.SortDescriptions.Insert(0, new SortDescription(currentHeader.Column.Header.ToString(), direction));
}
else
{
this.Source.SortDescriptions.Insert(0, new SortDescription(currentHeader.Column.Header.ToString(), ListSortDirection.Ascending));
}
this.Source.Refresh();
}
}
//group////////////////////
private void btnGroup_Click(object sender, RoutedEventArgs e)
{
this.Source.GroupDescriptions.Clear();
PropertyInfo pinfo = typeof(object).GetProperty(cmbGroups.Text);
if (pinfo != null)
this.Source.GroupDescriptions.Add(new PropertyGroupDescription(pinfo.Name));
}
WPF code is as below
<ListView ItemsSource="{Binding}" x:Name="LvItems" ButtonBase.Click="ListView_Click" IsSynchronizedWithCurrentItem="True" Grid.Row="1" Margin="0,22,0,43">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontSize="15" FontWeight="Bold" Text="{Binding}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
Since you are using WPF you shall use DataBindings. Expose your ICollectionView as a property and bind on it
public ICollectionView MyList
{
get
{
if(_mylist == null)
_mylist = CollectionViewSource.GetDefaultView(observableCollection);
return _mylist;
}
}
In the XAML you apply the binding as follows
<ListView ItemsSource="{Binding Path=MyList}"/>
And now you apply the sorting on that property
MyList.SortDescriptions.Remove(...);
MyList.SortDescriptions.Add(...);
MyList.GroupDescription.Add(...);
This has the drawback that every Remove or Add on a SortDescription or GroupDescription will refresh the ListView. Normally this is unwanted if you want to apply many sortings in one step. Then you should enclose the block with following:
using(MyList.DeferRefresh())
{
//put your changes in sorting and grouping here
}

Categories