Windows phone LonglistSelector not rendering all items - c#

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

Related

When you drag and drop the gui freezes

I have a drag and drop PopupBox in MaterialDesign. When drag and drop is done, the gui freezes and the data that is constantly renewed is not refreshed. How can I solve this Problem? Is it wrong to run in a separate thread? Is there just an overlooked point? Or is it all wrong?
my MouseUp Code
private void PortableButton_MouseUp(object sender, MouseButtonEventArgs e)
{
ThreadPool.QueueUserWorkItem(state => {
PortableButton.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
{
e.MouseDevice.Capture(null);
}));
});
}
MouseMove Code
private void PortableButton_MouseMove(object sender, MouseEventArgs e)
{
ThreadPool.QueueUserWorkItem(state => {
var ActuelHeight = MainBorder.ActualHeight;
var ActuelWidth = MainBorder.ActualWidth;
PortableButton.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
{
int _tempX = Convert.ToInt32(e.GetPosition(this).X);
int _tempY = Convert.ToInt32(e.GetPosition(this).Y);
if (_tempX < ActuelWidth && _tempX > 0 && _tempY < ActuelHeight && _tempY > 0)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
e.MouseDevice.Capture(PortableButton);
System.Windows.Thickness _margin = new System.Windows.Thickness();
_margin = MainGrid.Margin;
if (m_MouseX < _tempX)
{
_margin.Left += (_tempX - m_MouseX);
_margin.Right -= (_tempX - m_MouseX);
}
else
{
_margin.Left -= (m_MouseX - _tempX);
_margin.Right -= (_tempX - m_MouseX);
}
if (m_MouseY < _tempY)
{
_margin.Top += (_tempY - m_MouseY);
_margin.Bottom -= (_tempY - m_MouseY);
}
else
{
_margin.Top -= (m_MouseY - _tempY);
_margin.Bottom -= (_tempY - m_MouseY);
}
MainGrid.Margin = _margin;
m_MouseX = _tempX;
m_MouseY = _tempY;
}
}
}));
});
}
MouseLefButtonUp Code
double m_MouseX;
double m_MouseY;
private void PortableButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ThreadPool.QueueUserWorkItem(state => {
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() =>
{
m_MouseX = e.GetPosition(this).X;
m_MouseY = e.GetPosition(this).Y;
}));
});
}
Xaml Code
<Grid Name="MainGrid" Margin="96,308,156,0" VerticalAlignment="Top" Height="65" >
<materialDesign:PopupBox MouseUp="PortableButton_MouseUp" MouseLeftButtonUp="PortableButton_MouseLeftButtonUp" MouseMove="PortableButton_MouseMove" Name="PortableButton" Style="{StaticResource MaterialDesignMultiFloatingActionPopupBox}"
PlacementMode="BottomAndAlignCentres" ToolTipService.Placement="Right"
materialDesign:ShadowAssist.ShadowDepth="Depth3"
ToolTip="MenĂ¼">
<StackPanel>
<Button Name="SystemButton" ToolTip="System" PreviewMouseLeftButtonDown="SystemButton_PreviewMouseLeftButtonDown">
<Image Source="/Images/Icons/systemIcon.png" Width="45" ></Image>
</Button>
<Button Name="TestButton" ToolTip="Test" PreviewMouseLeftButtonDown ="TestButton_PreviewMouseLeftButtonDown">
<Image Source="/Images/Icons/testIcon.png" Width="30"></Image>
</Button>
<Button Name="PosButton" ToolTip="Pos" PreviewMouseLeftButtonDown ="PosClick">
<Image Source="/Images/Icons/positionIcon.png" Width="30"></Image>
</Button>
</StackPanel>
</materialDesign:PopupBox>
</Grid>
I add xaml code. There is constantly refreshing data on the screen. I get these with a special protocol with serialPort. Since it will be a very long code, it can be tried with the for loop that counts in the timer.

And again. Make DropDownButton opens on mouseEnter and hide when mouse leaves

I am using MahApps and MVVM Light. And I want to make DropDownButton opens on mouse enter. And hide it when mouse cursor leaves button and opened menu. For code simplification, I don't write code with EventToCommand. I just write code behind
XAML
<controls:DropDownButton x:Name="ddbVolume" Width="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}"
ItemsSource="{Binding AudioControls}"
Icon="{DynamicResource appbar_settings}" BorderThickness="0"
ArrowVisibility="Collapsed"
Loaded="OnDropDownButtonLoaded" MouseEnter="OnDropDownButtonMouseEnter">
</controls:DropDownButton>
and .cs
private void OnDropDownButtonMouseEnter(object sender, MouseEventArgs e)
{
var dropDownButton = sender as DropDownButton;
if (dropDownButton != null && !dropDownButton.IsExpanded)
{
dropDownButton.IsExpanded = true;
}
}
private void OnDropDownButtonLoaded(object sender, RoutedEventArgs e)
{
var dropDownButton = sender as DropDownButton;
if (dropDownButton != null)
{
var template = dropDownButton.Template;
var menu = (ContextMenu)template.FindName("PART_Menu", dropDownButton);
menu.MouseLeave += (o, args) =>
{
if (dropDownButton.IsExpanded && !dropDownButton.IsMouseOver && !menu.IsMouseOver)
{
dropDownButton.IsExpanded = false;
}
};
menu.PreviewMouseMove += (o, args) =>
{
if (!dropDownButton.IsExpanded)
{
return;
}
var x = args.GetPosition(menu).X;
var y = args.GetPosition(menu).Y;
if (x < 0 | y < 0 | x > menu.ActualWidth | y > menu.ActualHeight)
{
menu.ReleaseMouseCapture();
}
};
}
else
{
this._logger.Debug($"Error loading DropDownButton");
}
But it does not work. The DropDownButton is only flicker on mouse over. Please, give me a proper solution, or any usefull advice to solve this problem.
If the menu is appearing at all then your opening logic is good, but then it disappears, meaning that your own code is somehow closing it.
Stick a breakpoint on the line where you set dropDownButton.IsExpanded = false, and you'll see that's it's being called I'm sure. You can then use the debugger to see why it's been invoked and fix the problem in your xaml that's causing the system to think that your mouse has left the menu.
Maybe, you should subscribe the MouseLeave Event. And you could fix your Actions.
I have made a solution. And it works as i expect. The root of the problem was, that DropDownButton uses ContextMenu to show list items. And this control is based on Popup, which uses his own window. And MouseLeave fired not at time, when mouse coursor was not over it, but when it's lost focus.
XAML
<controls:DropDownButton x:Name="ddbVolume" Width="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}"
ItemsSource="{Binding AudioControls}"
Icon="{DynamicResource appbar_settings}" BorderThickness="0"
ArrowVisibility="Collapsed">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<command:EventToCommand Command="{Binding Source={x:Static commands:CommonCommands.DropDownButtonLoadedCommand}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseEnter">
<command:EventToCommand Command="{Binding Source={x:Static commands:CommonCommands.DropDownButtonMouseEnterCommand}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</controls:DropDownButton>
And a ViewModel code (I know it's not a VM, but it works the same way)
In static class I define commands that can be used anywhere in my application.
public static class CommonCommands
{
private static ICommand dropDownButtonLoadedCommand;
private static ICommand dropDownButtonMouseEnterCommand;
public static ICommand DropDownButtonLoadedCommand => dropDownButtonLoadedCommand;
public static ICommand DropDownButtonMouseEnterCommand => dropDownButtonMouseEnterCommand;
static CommonCommands()
{
dropDownButtonLoadedCommand = new RelayCommand<RoutedEventArgs>(DropDownButtonLoaded, x => true);
dropDownButtonMouseEnterCommand = new RelayCommand<MouseEventArgs>(DropDownButtonMouseEnter, x => true);
}
private static void DropDownButtonLoaded(RoutedEventArgs args)
{
var dropDownButton = args.Source as DropDownButton;
if (dropDownButton != null)
{
var template = dropDownButton.Template;
var menu = (ContextMenu)template.FindName("PART_Menu", dropDownButton);
var button = (Button)template.FindName("PART_Button", dropDownButton);
menu.MouseLeave += (o, e) =>
{
if (dropDownButton.IsExpanded && !dropDownButton.IsMouseOver && !menu.IsMouseOver)
{
dropDownButton.IsExpanded = false;
}
};
menu.PreviewMouseMove += (o, e) =>
{
if (!dropDownButton.IsExpanded || !menu.IsOpen)
{
return;
}
var x = e.GetPosition(menu).X;
var y = e.GetPosition(menu).Y;
if (x < 0 | y < -button.ActualHeight | x > menu.ActualWidth | y > menu.ActualHeight)
{
menu.ReleaseMouseCapture();
}
};
}
}
private static void DropDownButtonMouseEnter(MouseEventArgs args)
{
var dropDownButton = args.Source as DropDownButton;
if (dropDownButton != null && !dropDownButton.IsExpanded)
{
dropDownButton.IsExpanded = true;
}
}
}
I know there are some little defects. For example, "expression y < -button.ActualHeight" is not good at all. the proper way is to use button.IsMouseOver in MouseLeave event.

How do I Random all the items in the listbox?

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);
}

default selection is not working in wpf

here i m using a wpf ComboBox control and binding it using the datasource.
but my combobox is unable to set default seletion of first index which i give
manualy during the time to binding. here my code shown below can any one tell me how to set default item in combox box.
//Xaml
<ComboBox Height="23" HorizontalAlignment="Left" Margin="142,11,0,0" Name="cmbProductType" VerticalAlignment="Top" Width="180" ItemsSource="{Binding}" />
//Code
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ClsControl.GetProductTypeList(cmbProductType);
}
public static void GetProductTypeList(ComboBox ddlProductType)//Add By Sandeep On 11-03-2013
{
try
{
DataTable dtProductType = null;
try
{
ClsDataLayer objDataLayer = new ClsDataLayer();
dtProductType = objDataLayer.ExecuteDataTable("COMNODE_PROC_GetProductTypeList");
if (dtProductType != null && dtProductType.Rows.Count > 0)
{
DataRow drCardType = dtProductType.NewRow();
drCardType[0] = -1;
drCardType[1] = "< -- Select Card Type -- >";
ddlProductType.SelectedValue = -1;
dtProductType.Rows.InsertAt(drCardType, 0);
ddlProductType.ItemsSource = dtProductType.DefaultView;
ddlProductType.DisplayMemberPath = "PRODUCT_TYPE";
ddlProductType.SelectedValuePath = "PRODUCT_TYPE_ID";
}
}
catch (Exception)
{
throw;
}
}
catch
{
}
}
Try updating your XAML to this:
<ComboBox Height="23"
HorizontalAlignment="Left"
Margin="142,11,0,0"
Name="cmbProductType"
VerticalAlignment="Top"
Width="180"
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True" />
Also, use SelectedIndex instead when you select the item:
ddlProductType.SelectedIndex = 0;
dtProductType.Rows.InsertAt(drCardType, 0);
ddlProductType.ItemsSource = dtProductType.DefaultView;
ddlProductType.DisplayMemberPath = "PRODUCT_TYPE";
ddlProductType.SelectedValuePath = "PRODUCT_TYPE_ID"

Dynamically update a data bound listbox C# WPF

So despite finding articles online I still cannot figure this out.
I have a Listbox
<ListBox HorizontalAlignment="Left" Margin="54,35,0,0" Name="resultsbox" VerticalAlignment="Top" Width="382" Visibility="Collapsed">
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding nameElement}"/>
</StackPanel>
</DataTemplate>
</ListBox>
That is databound to
ObservableCollection<string> results = new ObservableCollection<string>();
and is updated with
private void searchbox_TextChanged(object sender, TextChangedEventArgs e)
{
resultsbox.Visibility = Visibility.Visible;
resultsbox.ItemsSource = results;
if (results.Count == 0)
{
foreach (ele item in eles)
{
if (!results.Contains(item.nameElement))
{
results.Add(item.nameElement);
}
}
}
else
{
resultsbox.Items.Clear();
}
if (searchbox.Text.Equals(""))
{
window1.Height = 47;
resultsbox.Visibility = Visibility.Collapsed;
}
if (resultsbox.Items.Count == 0)
{
resultsbox.Visibility = Visibility.Collapsed;
window1.Height = 47;
}
else{
window1.Height = 47 + (22 * resultsbox.Items.Count);
}
}
It loads ALL the data in there but WILL NOT UPDATE!
If I do resultsbox.clear() it says you can't clear bound items. If you try and clear the source it does nothing. If you try and set the resultsbox itemsource to null and clear the source then rebind it, nothing. If you try and bind the listbox to an empty source it does nothing....
The answer was changing the foreach loop in the update from
resultsbox.ItemsSource = results;
if (results.Count == 0)
{
foreach (ele item in eles)
{
if (!results.Contains(item.nameElement))
{
results.Add(item.nameElement);
}
}
}
to
results.Clear();
foreach (ele item in eles)
{
if (item.nameElement.ToLower().Contains(searchbox.Text.ToLower()))
{
results.Add(item.nameElement);
}
}
resultsbox.ItemsSource = results;
You can try using Two-Way Mode Binding to achieve your requirement IMO,
<ListBox HorizontalAlignment="Left" Margin="54,35,0,0" Name="resultsbox" VerticalAlignment="Top" Width="382" Visibility="Collapsed">
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding nameElement, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>

Categories