I want to search an item in an ItemsControl and scroll to the specific item that I'm looking for.
This is my XAML code:
<ItemsControl Grid.Row="2" x:Name="MessagesItemsCtrl" Grid.Column="1" Margin="0,5,0,0" ItemsSource="{Binding NewChatter}" ItemTemplate="{DynamicResource MessagesDataTemplate}" AllowDrop="True" Drop="MessagesItemsCtrl_Drop"
ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer x:Name="myscroll" ScrollChanged="MessagesItemsCtrl_ScrollChanged">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
Does anyone have suggestions for my problem?
Don't add the ScrollViewer to the ItemsControl. Simply use the ListBox instead.
You can search for an item by iterating over the source collection (NewChatter in your case).
To scroll the selected item into the view:
Add a binding to SelectedItem.
Set the source property of this binding to update the ListBox.SelectedItem (a Binding set on this property binds TwoWay by default).
This will trigger the SelectionChanged event of the ListBox.
Call ListBox.ScrollIntoView() to scroll any item into the view.
MainWindow.xaml
<ListBox ItemsSource="{Binding NewChatter}"
SelectedItem="{Binding SelectedNewChatterItem}"
OnSelectedItemChanged="Selector_OnSelectionChanged" />
MainWindow.xaml.cs
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = sender as ListBox;
listBox.ScrollIntoView(listBox.SelectedItem);
}
Related
i like to customize my LongListSelector or ListBox in my own way so can any one help me to design it.. MY Code..
<StackPanel HorizontalAlignment="Left" Height="345" Margin="10,234,0,0" VerticalAlignment="Top" Width="413">
<phone:LongListSelector x:Name="list_organization" Height="340" Margin="10,0"/>
</StackPanel>
This is my code to bind the long list..
org = await client.searchOrganization(txtQuery.Text);
if (org != null)
{
var query = from c in org
select new { c.name,c.id,c.time,.. };
list_organization.ItemsSource = query.ToList();//bind the query to longlist
}
i want like this design page..
how to do it...?
First of all, remove explicit widths and heights. And if you only have a single LongListSelector inside the StackPanel, you can remove the StackPanel.
Individual items for the listbox-like containers is done by using the DataTemplate to replace ItemTemplate. Check the following MSDN link for more information: ListBox Styles and Templates.
Basically, here is how you do it:
<phone:LongListSelector x:Name="list_organization" Height="340" Margin="10,0"
ItemsSource="{Binding People}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<!-- your XAML for individual item goes here -->
<TextBlock Text="{Binding FirstName}" />
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
What is the best solution to have something like a web_application DetaisView control(horizontal dataGrid with just one row!) with binding, insert and update features?
using horizontal datagrid
using a special listview
...
Create a user control that contains the specified fields you need to edit an item of your list
<UserControl x:Class="DisplayUserControl" ...>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Name"/>
<TextBox Text="{Binding Name}"/>
</StackPanel>
...
</UserControl>
Bind the user control datacontext to the selected item of your List
<MainWindow>
<ListBox ItemsSource="{Binding to your data}" x:Name="list"/>
<local:DisplayUserControl DataContext="{Binding SelectedItem, ElementName=list}"/>
</MainWindow>
I just used a simple ListBox for displaying data
I have item template for the panorama control. In that template, i have listbox with listItem template. I have problem with selection changed event in the list box.
<phone:PhoneApplicationPage.Resources>
<CollectionViewSource x:Key="SlideItemList" Filter="collectionView_Filter"/>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Panorama control-->
<controls:Panorama x:Name="AppPano" ItemsSource="{Binding SlidesCollections}" SelectionChanged="AppPano_SelectionChanged" >
<controls:Panorama.Background>
<ImageBrush ImageSource="PanoramaBackground.png"/>
</controls:Panorama.Background>
<controls:Panorama.ItemTemplate>
<DataTemplate>
<Grid VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,-100,0,0">
<StackPanel HorizontalAlignment="Center" Height="250" Width="200" VerticalAlignment="Top">
<TextBlock Text="{Binding Title}" HorizontalAlignment="Center" FontSize="200" Width="Auto"/>
</StackPanel>
<ListBox x:Name="ItemsList" ItemsSource="{Binding Source={StaticResource SlideItemList}}" Margin="0,250,0,0" VerticalAlignment="Top" SelectionChanged="ItemsList_SelectionChanged" Height="430">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="ImgStack" HorizontalAlignment="Left" Height="430" VerticalAlignment="Top" Width="370" Margin="50,0,0,0">
<Image Height="350" Width="360" Source="{Binding Image}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
</controls:Panorama.ItemTemplate>
</controls:Panorama>
</Grid>
Xaml.cs
private void keyItemsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listbox = (ListBox)sender;
var conGen = listbox.ItemContainerGenerator;
var item = (UIElement)conGen.ContainerFromIndex(listbox.SelectedIndex);
if (item != null)
{
int selectedItemList = listbox.SelectedIndex;
if (sLasListItem != selectedItemList)
{
// navigate to another page
sLasListItem = selectedItemList;
}
}
}
Binding UI elements works perfectly.
Problem:
1. When i select new item from the list in one panorama item page, it will fire, the same selection changed event for all panorama items.
Ex:
Let's consider, i have 4 panorama items. I selected 2nd item from the 1st panorama item list box. this selection changed event executed 4 times.
My expectation was, when i select new item from the list, this event should fire only one time for the corresponding panorama item.
Pls suggest me, how to do it...
It's because you're binding the same list 4 times. (Assuming that SlidesCollections contains 4 items.)
Because each list is the same data, when you change the selected item in one view of that data, it is actually changed in the underlying (albeit filtered) list.
You should look to create separate lists in the view model instead.
I want to know if a double-clicking functionality for a ListBox can easily be build. I have a ListBox with a collection as ItemSource. The collection contains own data-types.
<ListBox ItemsSource="{Binding Path=Templates}"
ItemTemplate="{StaticResource fileTemplate}">
I defined a DataTemplate for my Items, which consists of StackPanels and TextBlocks.
<DataTemplate x:Key="fileTemplate">
<Border>
<StackPanel>
<TextBlock Text="{Binding Path=Filename}"/>
<TextBlock Text="{Binding Path=Description}"/>
</StackPanel>
</Border>
</DataTemplate>
Now I want to detect a double-click-event for the double-clicked list-item. Currently I tried with following, but it doesn't work because it doesn't return the Item bound to the ListBox but the TextBlock.
if (TemplateList.SelectedIndex != -1 && e.OriginalSource is Template)
{
this.SelectedTemplate = e.OriginalSource as Template;
this.Close();
}
What is a clean way to handle a double-click-event on an item in a ListBox, if the icons are not ListBoxItems, but own DataTemplates?
I've been playing around with this and I think I've got there...
The good news is, that you can apply a style to your ListBoxItem and apply a DataTemplate - the one does not preclude the other...
In other words, you can have something like the following:
<Window.Resources>
<DataTemplate x:Key="fileTemplate" DataType="{x:Type local:FileTemplate}">
...
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Templates}"
ItemTemplate="{StaticResource fileTemplate}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="MouseDoubleClick" Handler="DoubleClickHandler" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
and then implement a handler in your Window, like
public void DoubleClickHandler(object sender, MouseEventArgs e)
{
// item will be your dbl-clicked ListBoxItem
var item = sender as ListBoxItem;
// Handle the double-click - you can delegate this off to a
// Controller or ViewModel if you want to retain some separation
// of concerns...
}
I've got a TabControl whose ItemsSource is bound to an observable collection of views (UserControls) each which have as its root element a TabItem. However, when it is displayed, the Header text is in content of each TabItem, as if UserControl wrapper is causing conflicts:
The TabControl is in SmartFormView.xaml:
<UserControl x:Class="TestApp.Views.SmartFormView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel
Margin="10">
<TextBlock Text="{Binding Title}"
FontSize="18"/>
<TextBlock Text="{Binding Description}"
FontSize="12"/>
<TabControl
Margin="0 10 0 0"
ItemsSource="{Binding SmartFormAreaViews}"/>
</StackPanel>
</UserControl>
What do I have to change so that TabItems are displayed as TabItems inside the TabControl?
Here are the TabItem views called SmartFormAreaView.xaml:
<UserControl x:Class="TestApp.Views.SmartFormAreaView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TabItem Header="This is the header">
<StackPanel Margin="10">
<TextBlock Text="this is the content"/>
</StackPanel>
</TabItem>
</UserControl>
And here is where I create and load each view into the ObservableCollection:
var areas = from area in xmlDoc.Descendants("area")
select area;
foreach (var area in areas)
{
SmartFormArea smartFormArea = new SmartFormArea();
smartFormArea.IdCode = area.Attribute("idCode").Value;
smartFormArea.Title = area.Attribute("title").Value;
SmartFormAreaPresenter smartFormAreaPresenter = new SmartFormAreaPresenter(smartFormArea);
SmartFormAreaViews.Add(smartFormAreaPresenter.View as SmartFormAreaView);
}
For any ItemsControl, if the items added to its Items collection (either directly or via ItemsSource) are not instance of that control's item container, then each item is wrapped in an instance of the item container. The item container is a class such as TabItem or ListBoxItem. The item container is normally a ContentControl or HeaderedContentControl, and your actual item is assigned to its Content property, so you can use templates etc to control how the content is presented. You can also style the item container itself using the ItemControl's ItemContainerStyle property.
In this particular case, you should bind ItemsSource to a list of SmartFormAreaPresenters. Then use something like this for the tab control:
<TabControl ItemsSource="{Binding SmartFormAreaPresenters}">
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="{Binding HeaderText}" />
</Style>
</TabControl.ItemContainerStyle>
<TabControl.ContentTemplate>
<DataTemplate DataType="{x:Type local:SmartFormAreaPresenter}">
<local:SmartFormAreaView />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
where HeaderText is a suitable property on your SmartFormAreaPresenter. You should also remove the TabItem from your SmartFormAreaView definition. The DataContext of each View will automatically be set to the appropriate Presenter.
See Dr. WPF's blog for an excellent discussion of various ItemsControl related topics.
The TabControl will accept your controls as its controls only if they can be cast to TabItem, not UserControl, or SmartFormAreaView, etc.
So you either fill regular TabItems with your visual tree, or you subclass TabItems, or you subclass the TabControl to override its IsItemItsOwnContainerOverride method, to accept your type as the container.
The method should look as follows:
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is YourControlTypeHere || item is TabItem;
}