I have my xaml code
<ListView x:Name="ListVideo"
ItemsSource="{x:Bind ScreenList}"
VerticalAlignment="Stretch"
FlowDirection="LeftToRight"
Grid.Row="1"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<controls:UniformGrid></controls:UniformGrid>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="White"
BorderBrush="White"
BorderThickness="1">
<SwapChainPanel x:Name="swapChain"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate></ListView>
with ScreenList is type of ObservableCollection. So the question is how can I add new SwapChainPanel in the ListView?.
I intend to add SwapChainPanel item, and with each item I use DirectX to render video, so i want to get the object SwapChainPanel item in code-behind to process then.
Thanks.
So the question is how can I add new SwapChainPanel in the ListView
You have placed SwapChainPanel in the Listview DataTemplate, and current listview ItemsSource is ObservableCollection. So you just need add new item into ObservableCollection, the listview will render new item automatically.
so i want to get the object SwapChainPanel item in code-behind
You could get itemContainer with ContainerFromItem method, and find swapChain with name in ContentTemplateRoot.
var container = MyList.ContainerFromItem(MyList.Items[0]) as ListViewItem;
var swapChain = (container.ContentTemplateRoot as Grid).FindName("swapChain");
Update
As the Hoka Biu comment below, you could also get swapChain instance within SwapChainPanel Loaded event.
<SwapChainPanel Loaded="swapChain_Loaded"/>
private void swapChain_Loaded(object sender, RoutedEventArgs e)
{
var swapChain = sender as SwapChainPanel;
}
Related
I have following structure :
<GridView x:Name="GVmain" SelectionChanged="GVmain_SelectionChanged_1" ItemsSource="{Binding DateItemsView}" SelectionMode="None" Visibility="Visible" Padding="120,0,0,0" ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.VerticalScrollMode="Disabled" Grid.Row="1" ItemContainerStyle="{StaticResource GridViewItemStyleATLIST}">
<!--<StackPanel Orientation="Horizontal">-->
<GridView.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,30,0" Width="400" DataContext="{Binding}" >
<Grid.RowDefinitions>
...
Using Xamwinrt toolkit, is there any way to select GVmain's selecteditem's Child Grid?
I think I can only cast SelectedItem to the Type of it's ItemSource.
Use ListView.ContainerFromItem, passing in ListView.SelectedItem. This will give you the ListViewItem of the SelectedItem. You can then use the normal GetDescendents or GetFirstDescendantOfType to parse the visual tree.
i.e.
// ContainerFromItem seems to have issues at times, so use ContainerFromIndex.
//var itemContainer = GVmain.ContainerFromItem(GVmain.SelectedItem);
var itemContainer = GVmain.ContainerFromIndex(GVmain.SelectedIndex);
var rootGrid = itemContainer.GetFirstDescendantOfType<Grid>();
Hope this helps and happy coding!
I have a fairly straight forward listview control for my Windows 8 XAML/C# application. I am binding the listview to a PersonList and that works correctly. However, what I'd like to do and haven't been able to find the answer for is I want the to click an item in the listview and be able to display the PersonSingle object to the other textboxes on the screen.
I've read some posts that indicate that the listview may not be the right control for this operation. Am I missing something in my listview that would allow me to do this operation or should I use a different control?
<ListView
x:Name="itemListView"
Visibility="Visible"
Width="auto"
Height="auto"
ItemsSource="{Binding PersonList, Mode=TwoWay}"
SelectedItem = "{Binding PersonSingle, Mode=OneWay}"
ItemTemplate="{StaticResource person80Template}"
SelectionMode="Single"
Grid.Row="1"
Grid.Column="1"
VerticalAlignment="Stretch">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="7,7,0,0">
<Button
AutomationProperties.Name="PersonValue"
Content="{Binding PersonName}"
Style="{StaticResource TextButtonStyle}"/>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
UPDATE:
So I figured out how to do it in a non-MVVM way (or at least not in a true MVVM way)
I added an ItemClick event to my ListView:
ItemClick="itemListView_ItemClick"
And then in the code behind I added the following:
private void itemListView_ItemClick(object sender, ItemClickEventArgs e)
{
VM.PersonSingle = ((Person)e.ClickedItem);
}
That works, but like I said, it doesn't feel very MVVM'ish. If you have any suggestions on how to make it work without having to manually set the PersonSingle object please answer below.
Your ItemClick solution is the right solution. You could create an attached behavior if you are opposed to handling events, but that's your choice.
I am a ListBox with images from IsolatedStorage, in which the user may select an image to use. I would like to somehow show the user which image they have currently selected, or pressed, within the Listbox via a border around the image (or another way if better). I am not sure exactly how to get the currently selected image and place a border around that image. I am currently using the SelectionChanged event of the ListBox to attempt this functionality. What I have so far is as follows:
MainPage.xaml
<ListBox x:Name="Recent" ItemsSource="{Binding Pictures}" Margin="8"
SelectionChanged="recent_SelectionChanged" toolkit:TiltEffect.IsTiltEnabled="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image x:Name="recentImage" Source="{Binding Source}" Margin="12" Width="115"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
MainPage.xaml.cs
private void recent_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//Place border round currently selected image
//?
}
Any thoughts?
Update to Fix
MainPage.xaml
//within the ListBox DataTemplate
<Border>
<Image x:Name="recentImage" Source="{Binding Source}" Margin="12" Width="115"/>
</Border>
MainPage.xaml.cs
//within recent_SelectionChanged
var lb = sender as ListBox;
var lbi = lb.ItemContainerGenerator.ContainerFromItem(lb.SelectedItem) as ListBoxItem;
lbi.BorderThickness = new Thickness(2, 2, 2, 2);
lbi.BorderBrush = new SolidColorBrush((Color)Application.Current.Resources["PhoneAccentColor"]);
I'd create another image on top of the image in your data template. This image would be mostly transparent with just the border and maybe a little tick (like Windows 8 apps have). Then I would toggle the visibility of this image when the item is selected.
Because the image would be mostly transparent it would show as a border around the selected image.
I use this technique to 'grey out' items (by using a solid black image with ~10% opacity) and it works really well.
You should be able to simply bind the visibility to the selected property - though you'd need a converter to convert between boolean and visibility.
<DataTemplate>
<Image x:Name="recentImage" Source="{Binding Source}" Margin="12" Width="115"/>
<Image x:Name="borderImage" Source="Images/borderimg.png" Margin="12" Width="115" Visibility="Collapsed"/>
</DataTemplate>
Then:
private void recent_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//set the visibility property of the selected item to 'Visible'
}
To keep things simple let's just say I have a c# Windows Store Project for Windows 8 that has the following items:
GridView (PlatformsGrid)
List«PlatformSearchResult» (allPlatforms)
DataTemplate (PlatformDataTemplate) in standardstyles.xaml
allPlatforms is a collection of "PlatformSearchResult"objects populated from an online API, and has the following 3 properties:
ID
Name
Alias
I am able to add a new item to the gridview for each object that exists in my allPlatforms collection, however the items are blank and do not show the data from my objects.
A quick summary of the current code looks like this:
XAML Markup:
<!-- Platforms Content -->
<GridView x:Name="PlatformsGrid" Grid.Row="1"
CanReorderItems="True" CanDragItems="True"
ItemTemplate="{StaticResource PlatformDataTemplate}" >
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="2"
VerticalChildrenAlignment="Top" HorizontalChildrenAlignment="Center" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
Data Template
<!-- Platform Item Template -->
<DataTemplate x:Key="PlatformDataTemplate">
<Grid Background="#FF939598" Height="250" Width="250">
<Image Source="/SampleImage.png" Stretch="UniformToFill"/>
<StackPanel Orientation="Vertical" Background="#CC000000"
Height="90" VerticalAlignment="Bottom">
<TextBlock Text="{Binding Name}"
Margin="10,3,0,0" Width="242" Height="62"
TextTrimming="WordEllipsis" TextWrapping="Wrap" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Alias}"
Margin="10,2,0,0" Width="186" Height="14"
TextTrimming="WordEllipsis" HorizontalAlignment="Left" FontSize="9" Opacity="0.49"/>
</StackPanel>
</Grid>
</DataTemplate>
Controlling Function
private async void FetchItemInfo_Loaded(object sender, RoutedEventArgs e)
{
// Get List of Top Games
List<PlatformSearchResult> allPlatforms = new List<PlatformSearchResult>();
allPlatforms = await GamesDB.GetPlatforms();
// Dynamically Create Platform Tiles
foreach (PlatformSearchResult platform in allPlatforms)
{
PlatformsGrid.DataContext = platform;
PlatformsGrid.Items.Add(platform);
}
}
How do I get the added items to show the appropriate object properties (ignoring the image for now), I'm just interested in populating the content of the TextBlocks.
I appreciate any help anyone can provide!
Thanks, Alex.
Bind the allplatforms list through a property to the gridview as the itemssource. This assumes, of course, that the datacontext for the gridview or the page is the class that contains your allplatforms property. If not, you'll have to do that too.
Set the datacontext either through code behind
this.grid.DataContext = class()//
or through binding
<!-- Platforms Content -->
<GridView x:Name="PlatformsGrid" Grid.Row="1"
CanReorderItems="True" CanDragItems="True"
ItemsSource = "{Binding AllPlatforms}"
ItemTemplate="{StaticResource PlatformDataTemplate}" >
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="2"
VerticalChildrenAlignment="Top" HorizontalChildrenAlignment="Center" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
You can check the Windows 8 app samples provided on msdn.
EDIT: Your platform object must have the properties for name and alias that you have added as Binding.
all you need to do in you controlling function is
private async void FetchItemInfo_Loaded(object sender, RoutedEventArgs e)
{
// Get List of Top Games
List<PlatformSearchResult> allPlatforms = new List<PlatformSearchResult>();
allPlatforms = await GamesDB.GetPlatforms();
PlatformsGrid.ItemsSource = allPlatforms;
}
In a continuation from my question here
I tried using the solution provided in the linked answer, however when I give it the image which the ListBox is binding to, it gives me the wrong position, because the Item Template is loading in a source URL rather than the actual image, and it seems the data is null.
My Item Template looks like this:
<ListBox ItemsSource="{Binding Items}"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
Height="64" Name="listBoxSource"
VerticalAlignment="Bottom"
SelectionChanged="listBoxSource_SelectionChanged" Canvas.Left="32" Canvas.Top="365" Width="596"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image x:Name="ListImage" Source="{Binding thumbnailURL}" Height="64" Width="64"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How do I get access to "ListImage" for the currently selected Item?
Every ItemsControl has an ItemsContainerGenerator, which (surprisingly enough) is responsible for generating a control for each item in the list. It provides a few useful methods for finding the container of a given item, and vice versa. You can use it like this:
private void listBoxSource_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = (ListBox) sender;
var containerGenerator = listBox.ItemContainerGenerator;
var container = (UIElement)containerGenerator.ContainerFromItem(listBox.SelectedItem);
}
You can then use the variable container with the solution from your other post to find the coordinates,
Point position = container.GetRelativePosition(Application.Current.RootVisual);
And on a side note, in your DataTemplate you don't need the StackPanel, since the ListBox is providing that with its ItemsPanelTemplate.
<DataTemplate>
<Image x:Name="ListImage" Source="{Binding thumbnailURL}" Height="64" Width="64"/>
</DataTemplate>
on tap event you can do this:
private void image_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
Image selectedImage = e.OriginalSource as Image;
}
is this what you need?
I would suggest a different solution because the way you are trying to solve it (finding the control) is prone to error.
Make the DataTemplate a resource and refer to it in the ListBox by using ItemTemplate="{StaticResource myTemplate}"
Next, when an item is selected, add a ContentControl to the Canvas, set its ContentTemplate to the same DataTemplate and the DataContext to the SelectedItem.
This way you only have to define the template once (one place to maintain it) and do not have to walk the VisualTree.