eventtocommand for dynamically created controls silverlight mvvm light - dynamic

I want to add a trigger to a dynamically created control but I couldn't. The event doesn't fire. This is my code.
<sdk:HierarchicalDataTemplate x:Key="NameTemplate"
ItemsSource="{Binding LstRs}"
ItemTemplate="{StaticResource RsTemplate}">
<TextBlock Text="{Binding Nom}" FontWeight="Bold" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<gs:EventToCommand Command="{Binding Path=StateCommand}"
CommandParameter="{Binding Text, ElementName=TextBoxSearch, Mode=OneWay}"
MustToggleIsEnabledValue="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</sdk:HierarchicalDataTemplate>
and the command is implemented in the view model.

IMHO, the most common error in such a case is that the command was not created - i.e. StateCommand == null - when the data is bound. Make sure you created the command in the constructor of you view-model.

Related

How do I create a two column layout using xaml RelativePanel?

I'd really like to use RelativePanel in a UWP app I'm writing, to simplify visual state.
This is what I want
I've tried to achieve this with the following XAML:
<RelativePanel>
<TextBlock x:Name="Title" Height="50" Margin="15" FontSize="24"
RelativePanel.AlignTopWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True">
</TextBlock>
<TextBox x:Name="Editor" Margin="15" Padding="20" HorizontalAlignment="Stretch"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.Below="Title"
RelativePanel.RightOf="FileList">
</TextBox>
<ListView x:Name="FileList" HorizontalAlignment="Stretch" Margin="15"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.Below="Title">
</ListView>
</RelativePanel>
This isn't working. Editor does not stretch. If I set Editor to RelativePanel.AlignRightWith="FilesList", it stretches past files list and fills the window.
Is there any way to do what I want with RelativePanel? Please don't post suggestions on how to do this in Grid, I can already do that - I want to use RelativePanel in this case
Your Editor control should have -
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.Below="Title"
RelativePanel.LeftOf="FileList"
RelativePanel.AlignBottomWithPanel="True"
Note it should be LeftOf, not RightOf. You will also need AlignBottomWithPanel set to True.

listVIew SelectionChanged and StorageFiles

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

Add behavior to RadioButton in ItemsControl (Windows 8 Search)

I'm implementing the search contract (results page) of a Windows 8 application. I've designed everything to follow MVVM. With that, I'm trying to wire up a command to the 'filtersItemsControl' that is provided in the search contract template for Windows 8.
<ItemsControl
x:Name="filtersItemsControl"
Canvas.ZIndex="1"
ItemsSource="{Binding Source={StaticResource filtersViewSource}}"
Visibility="{Binding ShowFilters, Converter={StaticResource BooleanToVisibilityConverter}}"
Margin="120,-3,120,30">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton
GroupName="Filters"
IsChecked="{Binding Active, Mode=TwoWay}"
common:CheckedCommandBehavior.Command="{Binding RelativeSource={RelativeSource Self}, Path=FilterChangedCommand}"
Style="{StaticResource TextRadioButtonStyle}">
<TextBlock Text="{Binding Description}" Margin="3,-7,3,10" Style="{StaticResource GroupHeaderTextStyle}" />
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The code above is my attempt to hook into 'FilterChangedCommand' which is a property of the ViewModel. The ViewModel also contains a list of properties that the ItemsControl is bound to (filtersViewSource). I think my issue is that I'm trying to bind the Command of the RadioButton to a property of filtersViewSource (which obviously does not exist) vs. the ViewModel.
So with that, I THINK the question here is basically, what binding expression can I used on the above RadioButton such that it will reference the ViewModel property.
FiltersViewSource should a property in viewmodel of some type, say "Foo". In that case, radio button will get datacontext of type Foo. So the property "FilterChangedCommand" should be in Foo class.

How to specify Command binding scope in MVVM?

I'm messing around with MVVM and I've hit a bit of a roadblock with binding commands to buttons. I have a few buttons in a View ( = UserControl) that are generated based on a list of objects I have.
My code looks like this:
(MainWindow)
<ItemsControl ItemsSource="{Binding ViewModels}" Margin="12,57,12,12" />
(UserControl)
<ItemsControl ItemsSource="{Binding AllConnections}" Margin="0,34,0,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Password}" Height="23" HorizontalAlignment="Left" Margin="114,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" Command="{Binding Path=ConnectCommand}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
But ConnectCommand isn't being called and I assume it's because XAML is looking for it in the AllConnections binding, rather than the ViewModels binding where it should. How do I specify this?
You should use Relative source to specify the ancestor. Something like this:
Command = "{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=ViewModel.CommandToBind}"
You can add your command to Resources and just use {StaticResource yourCommand}. This could significally simplify xaml.
Useful links: WPF Commands, How to declare Application level commands?Commands as XAML ResourcesMVVM Commanding inside of a datatemplate

Share context menu in WP7 xaml

I want to add a contextmenu to items in a listbox. Typically the answer is to add the contextmenu to the root of the item template. However, I am using a template selector, so there are multiple templates in use, depending on the data of each item in the listbox. This means I need to add the same contextmenu definition to each template, which is not very appealing.
One solution is to wrap the datatemplate in a ContentControl, which would give me a single place for the context menu definition. However, I believe this would add layout overhead that isn't necessary.
Another solution I tried is adding the ContextMenu to the resource dictionary, but I believe this ends up sharing the same object instance across all the uses, and due to the way ContextMenu is implemented, this also does not work.
A third solution is using the Loaded event to call a function which populates the context menu appropriately. However, this ends up moving a lot of code that ought to be in the XAML into code, and looks quite ugly. If there's some way of defining the context menu in xaml, and then just referencing that from code, I would find it appealing, but I don't quite see how to do that.
What is the right way to share the same ContextMenu across the templates in a template selector?
This is the ContentControl method, which works, but ends up adding two content controls to each item:
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu Loaded="ContextMenu_Loaded">
<toolkit:MenuItem Header="Delete"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<ContentControl ContentTemplate="{StaticResource MyTemplate}" Content="{Binding}"/>
</ContentControl>
</DataTemplate>
</ListBox.ItemTemplate>
How about adding the ContextMenu to the TemplateSelector?
<ListBox ItemsSource="{Binding}">
<ListBox.Resources>
<DataTemplate x:Key="MyTemplate">
<StackPanel>
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<local:CustomTemplateSelector Content="{Binding}">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Delete"
Click="MenuItem_Click" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<local:CustomTemplateSelector.TemplateOne>
<DataTemplate>
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource MyTemplate}"
Foreground="Blue" />
</DataTemplate>
</local:CustomTemplateSelector.TemplateOne>
<local:CustomTemplateSelector.TemplateTwo>
<DataTemplate>
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource MyTemplate}"
Foreground="Red" />
</DataTemplate>
</local:CustomTemplateSelector.TemplateTwo>
<local:CustomTemplateSelector.TemplateThree>
<DataTemplate>
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource MyTemplate}"
Foreground="Yellow" />
</DataTemplate>
</local:CustomTemplateSelector.TemplateThree>
</local:CustomTemplateSelector>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I ran this and it worked for me - give it a try and let me know if this was the effect you were looking for or not.