I have the following code that makes up a HubSection within a Hub.
<HubSection DataContext="{Binding Path=[0], Source={StaticResource groupedItemsViewSource}}" Padding="40,30,40,0">
<HubSection.Background>
<ImageBrush ImageSource="Images/BG.jpg" Stretch="UniformToFill" />
</HubSection.Background>
<HubSection.Header>
<TextBlock x:Uid="Section1Header" TextLineBounds="TrimToBaseline" OpticalMarginAlignment="TrimSideBearings" Text="English"/>
</HubSection.Header>
<DataTemplate>
<GridView
x:Name="itemGridView1"
Margin="-4,-4,0,0"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Items In Group"
ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource Standard240x320ItemTemplate}"
SelectionMode="Single"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
</GridView>
</DataTemplate>
</HubSection>
I have an AppBar set up as well, but I'm not sure how to tell the AppBar what is selected in the HubSection.
Please advise.
Edit: To clarify, I'm facing issues with implementing code such as itemGridView1.selectedItem because I'm being told it "does not exist in the current context".
Most of the advice regarding this issue centres on iterating through the visual tree of your Frame, but that doesn't seem to work well in the XAML Hub Section.
Instead, implement a SelectionChanged event in your GridView. When this is triggered, it will send details of the GridView sender, which can then be referenced for additional information such as .SelectedItem.
private void GridViewName_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var GridState = sender as GridView;
if(GridState.SelectedItems.Count>0)
{
// Do something
}
}
Related
I have the following ListBox
<ListBox x:Name="lbListItems"
<ListBox.ItemTemplate>
<DataTemplate>
<ToggleButton x:Name="btnItem">
<StackPanel Orientation="Horizontal" Width="956">
<toolkit:AutoCompleteBox x:Name="acbItem"</toolkit:AutoCompleteBox>
</StackPanel>
</ToggleButton>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How can I set the ItemsSource for acbItem in code behind ?
I cant access to it !
Use Loaded event is a solution.
<toolkit:AutoCompleteBox Loaded="myControl_Loaded" ...
private void myControl_Loaded(object sender, RoutedEventArgs e)
{
toolkit:AutoCompleteBox myCombo = sender as toolkit:AutoCompleteBox;
// Do things..
}
But it's better to use MVVM approach to set ItemsSource from XAML
I bind the ItemsSource property for the Listbox but it does not work, If I put the Listbox out of template it works !
Then you should specify a RelativeSource of the binding:
<toolkit:AutoCompleteBox x:Name="acbItem"
ItemsSource="{Binding DataContext.YourItemsSourceCollection, RelativeSource={RelativeSource AncestorType=ListBox}}" />
Simply replace "YourItemsSourceCollection" with the actual name of the propertty to bind to and keep the rest.
I am having problems with generating a click event for items inside an items control. I am new to xaml nad wpf. Can you the experts help me out. Below is the code that i have come up with but now having no clue on how to add a click event to for the generated items. Will very much appreciate your responses. Thank you for reading
<ItemsControl ItemsSource="{Binding Text, Source={StaticResource TextContainer}}">
<!--text is an object bein made public from TextToDisplay. There can be many objects released ratger than one in this case-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ItemWidth="100"
ItemHeight="100" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type sys:String}">
<Border CornerRadius="100"
Background="BlueViolet">
<Button Margin="20"
Content="{Binding}"
HorizontalContentAlignment="Center" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
probably the easiest thing you can do is create your own user control... make it a custom button and add click event to that control so everytime the listbox add your control it will already have a click_event built in.
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// add your code here.
}
then for the listbox do something like that...
private void AddItemsButton_Click(object sender, RoutedEventArgs e)
{
ListBoxTest.Items.Add(new UserControl1());
}
this adds a usercontrol button to the listbox everytime you click on a button titled "add items"
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.
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.
<ItemsControl Name="CanvasTableMap" ItemsSource="{Binding}" ItemsPanel="{DynamicResource ItemsPanelTemplate1}" ItemTemplate="{DynamicResource DataTemplate1}">
<ItemsControl.Resources>
<ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
<WrapPanel Background="{DynamicResource ContentBackground}" />
</ItemsPanelTemplate>
<DataTemplate x:Key="DataTemplate1">
<Button Canvas.Left="100" Content="{Binding Name}" Template="{DynamicResource ButtonTableTemplate}"></Button>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
Here is my code.No problem with that. I have created an adorner and i would like to add an adorner for each button when i want. It is a little difficult as i dont know how to get the Buttons. CanvasTableMap.Items returns the Model so i dont know how to get access to the controls efficiently.
An easy way to do that is to define a handler for the Loaded event of the button, and add the adorner in that handler:
XAML
<Button Canvas.Left="100" Content="{Binding Name}" ... Loaded="Button_Loaded" />
Code-behind
private void Button_Loaded(object sender, RoutedEventArgs e)
{
var button = (Button)sender;
var layer = AdornerLayer.GetAdornerLayer(button);
// Add the adorner
...
}
If you don't want to use code-behind, you can create an attached behavior (either with System.Windows.Interactivity or by creating an attached property)
You can use the ItemContainerGenerator to get the control created from the data (ContainerFromItem). Usually doing things that way is not such a good idea though.