listVIew SelectionChanged and StorageFiles - xaml

I have a listView with StorageFile elements(as each element represents .mp3 file)
<ListView x:Name="songList" HorizontalAlignment="Left" Height="680" Background="{Binding }" ItemsSource="{Binding ListOfStorageFiles , Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}" Margin="986,120,0,-80" VerticalAlignment="Top" Width="294">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So far I use folderPicker to get specific folder from the user and i bind all the files to the listView as a list of storageFiles. The files show up and im able to select them , but i have to change the mediaElement Source upon listView SelectionChanged. Unfortunately when i add SelectionChanged to listView the compiler tells me - Object reference not set to an instance of an object. Anyone know what cause this behavior ? Also is this the right approach for playing media files from a list(binding the storageFile to the list ).
EDIT : I probably have to use Interaction.Behaviors for EventName = "SelectionChanged" ?

I ended up with
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="SelectionChanged">
<core:InvokeCommandAction Command="{Binding OnSelectedSongFromList }" CommandParameter="{Binding ElementName=songList, Mode=TwoWay}"></core:InvokeCommandAction>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
Then in the VM i use the list to :
ListOfMedia.MoveTo((uint)asf.SelectedIndex);

Related

DataBinding ListView ItemTemplate UserControl

I have a ListView on my Windows Universal page. I am using a UserControl to define my ItemTemplate so that I can use the RelativePanel and VisualStateManager to control how my items appear depending on the screen size...
<ListView ItemsSource="{Binding Path=AllThings}"
ItemContainerStyle="{StaticResource ListViewItemStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<local:CrossingControl />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I have a button in my UserControl where I want to bind its Command to a command property in the ViewModel that is the DataContext of the list itself...
<UserControl ...>
<RelativePanel>
<StackPanel x:Name="crossedEntryPanel">
<Button Command="{Binding DataContext.DeleteCommand,
RelativeSource={RelativeSource Mode=TemplatedParent}}"
CommandParameter="{Binding}"
I have tried using the ElementName binding, but it doesn't seem to work (I suppose because my listview element name is defined in another xaml file). I have also tried the above RelativeSource binding, but that doesn't seem to work either. How can I bind this properly?
You can make use of Tag property to save the DataContext of ListView and use it in UserControl
Here how it is done
<ListView ItemsSource="{Binding Path=AllThings}" x:Name="listview"
ItemContainerStyle="{StaticResource ListViewItemStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<local:CrossingControl Tag="{Binding DataContext,ElementName=listview}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<UserControl x:Name="usercontrol" ...>
<RelativePanel>
<StackPanel x:Name="crossedEntryPanel">
<Button Command="{Binding Tag.DeleteCommand,ElementName=usercontrol}"
CommandParameter="{Binding}"
RelativeSource={RelativeSource Mode=TemplatedParent}}":- this points to controltemplate of button

how to assign resx resource to itemtemplate control

In my WP8 app, i have radio button where customized it through datatemplate and embedded a textblock in it. My question is how to assign a key from my resx resource file to assign text value, so that i can localize these datatemplate control names without any issues.
Below is my sample xaml:
<TextBlock x:Name="lblTileColor" TextWrapping="Wrap" Text="{Binding LocalizedResources.Themes_Tile_label, Source={StaticResource LocalizedStrings}}" />
<RadioButton x:Name="accentColor" GroupName="tileColor" IsChecked="true">
<RadioButton.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Width="25" Height="25" Fill="{StaticResource PhoneAccentBrush}"/>
<TextBlock Width="10"/>
<TextBlock x:Name="lblDefaultAccent" Text="{Binding LocalizedResources.Themes_Tile_Default, Source={StaticResource LocalizedStrings}}" />
</StackPanel>
</DataTemplate>
</RadioButton.ContentTemplate>
</RadioButton>
Here i am trying to assign Themes_Tile_Default resx key to textblock named lblDefaultAccent control.
With above code i am seeing xaml error (i.e. Invalid XAML) in Datatemplate section - if i assign text value directly with hardcoding it is working...
any help to resolve this?

Howto correctly bind RibbonGalleryCategory to a collection

I'm using Microsoft.Windows.Controls.Ribbon.
I want to have a dynamic combobox with picture buttons in my ribbon.
If I do this directly in xaml, I get what I want:
<ribbon:RibbonComboBox
SelectionBoxWidth="62"
VerticalAlignment="Center"
>
<ribbon:RibbonGallery SelectedValue="0"
SelectedValuePath="Content"
MaxColumnCount="1">
<ribbon:RibbonGalleryCategory>
<ribbon:RibbonButton Label="Histo" HorizontalContentAlignment="Stretch"
Command="{Binding NewHistogrammCommand}"
SmallImageSource="/Test;component/Resourcen/Histogramm32.png"
LargeImageSource="/Test;component/Resourcen/Histogramm32.png" />
<ribbon:RibbonButton Label="3D" HorizontalContentAlignment="Stretch"
Command="{Binding NewDreiDCommand}"
SmallImageSource="/Test;component/Resourcen/DreiD32.png"
LargeImageSource="/Test;component/Resourcen/DreiD32.png" />
</ribbon:RibbonGalleryCategory>
</ribbon:RibbonGallery>
</ribbon:RibbonComboBox>
But if I try to do this via binding to a collection this way:
<ribbon:RibbonComboBox
SelectionBoxWidth="62"
VerticalAlignment="Center"
IsEditable="True" >
<ribbon:RibbonGallery
MaxColumnCount="1">
<ribbon:RibbonGalleryCategory ItemsSource="{Binding LayoutContentTypeList, ElementName=mainWindow}">
<ribbon:RibbonGalleryCategory.ItemTemplate>
<DataTemplate>
<ribbon:RibbonButton Label="{Binding Header}" HorizontalContentAlignment="Stretch"
Command="{Binding Command}"
CommandParameter="{Binding CommandParameter}"
SmallImageSource="{Binding ImageSource}"
LargeImageSource="{Binding ImageSource}" />
</DataTemplate>
</ribbon:RibbonGalleryCategory.ItemTemplate>
</ribbon:RibbonGalleryCategory>
</ribbon:RibbonGallery>
</ribbon:RibbonComboBox>
I get
System.Windows.Data Error: 40 : BindingExpression path error: 'IsDropDownOpen' property not found on 'object' ''ContentPresenter' (Name='')'. BindingExpression:Path=IsDropDownOpen; DataItem='ContentPresenter' (Name=''); target element is 'RibbonButton' (Name=''); target property is 'NoTarget' (type 'Object')
The buttons work correctly, but how can I resolve this binding error?
I'm guessing that you've found a solution for your problem, but for other people coming across this post, looking for an answer, you can find a complete solution that you can download and examine at your leisure in the How do I add Galleries to my Ribbon? post at 'The official blog of the Windows Presentation Foundation Team'. The basic idea is as follows.
Whatever object that you set as the RibbonGallery.DataContext should have a collection property to bind to the RibbonGalleryCategory.ItemsSource property. The objects in that collection should have properties containing the values that you want to appear in the gallery items. Declare a HierarchicalDataTemplate for the RibbonGallery.CategoryTemplate to bind your properties. Here is an example from the linked post:
<Ribbon:RibbonGallery DataContext="{x:Static data:WordModel.StylesParagraphGalleryData}"
ItemsSource="{Binding CategoryDataCollection}"
ScrollViewer.VerticalScrollBarVisibility="Hidden">
<Ribbon:RibbonGallery.CategoryTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding GalleryItemDataCollection}">
<Border Background="LightGray">
<TextBlock Text="{Binding}" FontWeight="Bold" />
</Border>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="Images\Paragraph_32x32.png" />
<TextBlock Margin="10,0,0,0" Text="{Binding}" />
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</Ribbon:RibbonGallery.CategoryTemplate>
</Ribbon:RibbonGallery>

Binding Hyperlink to richtextblock in windows 8 Metro app

I am building a windows 8 metro app for fun/learning etc.
I have created a listview of text items that have descriptions, images etc. Inside the description, there are often hyperlinks that I would like to make clickable.
However, when binding to a textblock, xaml hyperlink code is displayed as text. Searching arround, it looks like I need to use a richtextblock for hyperlinks. I can't seem to figure out how to bind a hyperlink to it. I have found many examples from wpf showing how to extend the richtextblock using flowdocument. Flowdocument doesn't exist in the current consumer preview version of the framework.
I am reaching out to see if anyone has solved this issue or has any suggestions on what path to head down.
Edit:
Code I have Currently
right now I am just binding the "text" field from my Statuses Object to a textblock binding on "text"
I have URL's in the text field which I want to be able to make clickable.
As a test I was replacing the text field of the first object with hyperlink markup
ex.
feed_results[0].text = "<hyperlink .....
then trying to bind to texblock and richtextblock
Xaml
<ListView x:Name="ItemListView" ItemsSource="{Binding}" Background="Black" Width="372" VerticalAlignment="Top" Margin="50,0,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" MinHeight="100">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding user.profile_image_url}" Margin="0,0,15,0" VerticalAlignment="Top" />
<StackPanel Orientation="Vertical">
<TextBlock HorizontalAlignment="Left" Foreground="Gray" Text="{Binding user.name}" FontWeight="Bold" TextWrapping="Wrap" MaxWidth="200" />
<TextBlock HorizontalAlignment="Left" Foreground="Gray" Text="{Binding text}" TextWrapping="Wrap" MaxWidth="200" />
</StackPanel>
</StackPanel>
<StackPanel Margin="0,15,0,0" HorizontalAlignment="Right">
<TextBlock Text="{Binding created_at, Converter={StaticResource StringConverter},ConverterParameter=Released: \{0:d\}}" HorizontalAlignment="Center" Foreground="Gray" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
Backend Code
FeedResult<Statuses> r2 = await feed.StatusesAsync(1, 50);
if (!r2.HasError)
{
feed_results = r2.Result;
Dispatcher.Invoke(Windows.UI.Core.CoreDispatcherPriority.High, new Windows.UI.Core.InvokedHandler((o, a) =>
{
ItemListView1.ItemsSource = feed_results;
}), this, null);
}
Microsoft removed support for inline hyperlinks from Metro XAML. You can still use HyperlinkButton for non inline hyperlinks, or if your inline hyperlinks short (1-2 words) then you could place HyperlinkButton inside of InlineUIContainer in RichTextBlock. Later solution would require some code, just using binding won't do it.

Using different databinding sources within ListBox and ContextMenus

Here is the XAML:
<ListBox ItemsSource="{Binding Documents}" BorderBrush="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Title}" FontSize="12" FontWeight="Bold" />
<TextBlock Text="{Binding ID}" FontSize="10" FontStyle="Italic" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu ItemsSource="{Binding CategoryList}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem Command="{Binding AddDocumentToCategoryContextMenuCommand}" Header="{Binding Category.Name}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
Ok so the ListBox's ItemSource is bound to the Documents collection in the VM and properly renders the Titles and IDs
The Context Menu's ItemSource is bound to the CategoryList collection in the VM and properly renders the list of categories.
The problem I have is with the Command Binding:
Command="{Binding AddDocumentToCategoryContextMenuCommand}"
Since the ItemSource for the ContextMenu is already set, it tries to get the AddDocumentToCategoryContextMenuCommand from CategoryList. Obviously the command is not there, it is a member of the VM.
I do not want any references to the VMs or Models in the XAML. Everything is constructed using Unity and VM-View is associated in App.xaml:
<Application.Resources>
<DataTemplate DataType="{x:Type vms:FeedViewModel}">
<views:FeedView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vms:DocumentsViewModel}">
<views:DocumentsView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vms:ManagementViewModel}">
<views:ManagementView/>
</DataTemplate>
<DataTemplate DataType="{x:Type dev:DevelopmentViewModel}">
<dev:DevelopmentView />
</DataTemplate>
</Application.Resources>
How can I databind to a member of the VM from within the ContextItem.
Thanks.
UPDATED edit #1 starts Here
Here is the updated xaml (but still not working but some insight gained):
<ListBox ItemsSource="{Binding Documents}" x:Name="Results" BorderBrush="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Title}" FontSize="12" FontWeight="Bold" />
<TextBlock Text="{Binding ID}" FontSize="10" FontStyle="Italic" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu ItemsSource="{Binding CategoryList}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem Command="{Binding ElementName=Results, Path=DataContext.AddDocumentToCategoryContextMenuCommand}" Header="{Binding Category.Name}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
I have this example working for a simple example that does not use a ContextMenu. It appears that the ContextMenu (even though attached to the ListBox) is not part of the user control visual tree. The binding always comes back null / not found. I think the ContextMenu, because it is a floating "window" is constructed in its own tree and therefore cannot find the ListBox call "Results" in order to access the ListBox's DataContext.
Any thoughts on this? Any recommendations on how deal with?
Edit #2 Starts Here
In case you are are wondering, figured out the answer to the binding question:
This binding works:
Command="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AddDocumentToCategoryContextMenuCommand}
Hope this helps others with the same question.
One last update for completeness.
In order for the command to know which context menu item was clicked on, I had to change the xaml slightly (silly oversight):
<ListBox.ContextMenu>
<ContextMenu x:Name="Context" ItemsSource="{Binding CategoryList}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem Command="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AddDocumentToCategoryContextMenuCommand}"
CommandParameter="{Binding Category.ID}"
Header="{Binding Category.Name}" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</ListBox.ContextMenu>
Again, hope this helps others.
Use the ElementName property of the binding to specify that. You'd end up with something like this:
Command="{Binding ElementName=ViewModelObject
Path=AddDocumentToCategoryContextMenuCommand}"