1

I'm having a working datatemplate for a ListView with ItemTemplate

<ListView ItemTemplate="{StaticResource MYTEMPLATE}"             
          HorizontalAlignment="Center"
          ScrollViewer.VerticalScrollBarVisibility="Auto"
          ContinuumNavigationTransitionInfo.IsEntranceElement="True">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel VerticalAlignment="Bottom"/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

The Template looks like that:

<DataTemplate x:Key="GlobalBox">
        <Border Background="#FFFFFFFF" Margin="10 0 0 5" CornerRadius="2 2 15 2">
            <Grid Width="380">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <StackPanel Grid.Row="0" Tag="{Binding ID}" Name="ProfileInfo" Tapped="Profile_Tapped" Orientation="Horizontal" Margin="15 15 15 0">
                    <Grid Width="360" Margin="0 0 0 10">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="75"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="50"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Border Grid.Column="0" Height="45" Width="45" CornerRadius="5">
                            <Border.Background>
                                <ImageBrush ImageSource="{Binding ImagePath}" Stretch="UniformToFill"/>
                            </Border.Background>
                        </Border>
                        <StackPanel Grid.Column="1" Orientation="Vertical" Margin="0 5 0 0">
                            <TextBlock Text="{Binding Name}" Foreground="Black" FontSize="18" FontWeight="Bold"></TextBlock>
                            <TextBlock Text="{Binding Handle}" Foreground="DarkGray" FontSize="12"/>
                        </StackPanel>
                        <Image Grid.Column="2" Source="Assets/ActionIcons/logo_blue_32.png" Width="32" VerticalAlignment="Top"></Image>
                    </Grid>
                </StackPanel>
                <StackPanel  Grid.Row="1" Margin="14.5,0,0,0" Height="Auto">
                    <StackPanel Name="TweetContent" Tag="{Binding ID}" Margin="15 0 15 0" Tapped="Content_Tapped">
                        <TextBlock Text ="{Binding Content}" TextWrapping="Wrap" Foreground="Black" FontSize="14" Margin="0 0 0 10"/>
                        <ItemsControl  ItemsSource="{Binding ContentImages}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Image Source="{Binding }" MaxWidth="350" Margin="0 0 0 5"  HorizontalAlignment="Center"></Image>
                                    </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                        <TextBlock Foreground="DarkGray" Text="{Binding DateSend}" FontSize="10"></TextBlock>
                    </StackPanel>
                    <StackPanel Name="ActionButtons">
                        <Grid Tag="{Binding ID}" Width="380" Height="25" Margin="0 0 0 10">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>

                            <Button Grid.Column="0" HorizontalAlignment="Center" Margin="20 0 0 0" Style="{StaticResource replyActionButton}" Tapped="Reply_Tapped"></Button>

                            <ToggleButton Grid.Column="2" HorizontalAlignment="Center" 
                                          Style="{StaticResource retweetActionButton}" 
                                          Tapped="Retweet_Tapped"></ToggleButton>
                            <TextBlock Grid.Column="3" HorizontalAlignment="Left" Margin="-15 0 0 0" VerticalAlignment="Center" Text="{Binding RetweetCount}" Foreground="DarkGray"/>

                            <ToggleButton Grid.Column="4" HorizontalAlignment="Center" 
                                          Style="{StaticResource likeActionButton}" 
                                          IsChecked="{Binding LikeState}"  
                                          Tapped="Favourite_Tapped"></ToggleButton>
                            <TextBlock Grid.Column="5"  HorizontalAlignment="Left" Margin="-15 0 0 0" VerticalAlignment="Center" Text="{Binding LikeCount}" Foreground="DarkGray"/>
                        </Grid>
                    </StackPanel>
                </StackPanel>
            </Grid>
        </Border>
    </DataTemplate>

And now when I put the template in the app.xaml file I am getting the following compile error

Events cannot be set in the Application class XAML file

This makes sense for me, but how can I do it anyway? Can I pass the different events like a variable or something into the datatemplate?

//UPDATE - SOLUTION WAY2 using the USERCONTROL:

I've made a UserControl out of the code above and implemented it in the ListView.

<ListView Grid.Row="1" Margin="0 0 0 5"       
        x:Name = "standardBox"
        HorizontalAlignment="Center"
        ScrollViewer.VerticalScrollBarVisibility="Auto"
        ContinuumNavigationTransitionInfo.IsEntranceElement="True">
    <ListView.ItemTemplate>
        <DataTemplate>
            <local:UCGlobal></local:UCGlobal>
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel VerticalAlignment="Bottom"/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>
Noam M
  • 3,156
  • 5
  • 26
  • 41
Ulpin
  • 179
  • 1
  • 14

3 Answers3

2

You could use a few alternatives:

  1. Use the command property of the buttons inside your templates (take care that your DataContext is set correct, to avoid binding errors):

    <DataTemplate x:Key="MyTemplate">
        <StackPanel>
            <Button x:Name="button1" Content="Button1" Command="{Binding Btn1Command}" CommandParameter="{Binding ElementName=button1}"/>
            <Button x:Name="button2" Content="Button2" Command="{Binding Btn2Command}" CommandParameter="{Binding ElementName=button2}"/>
            <Button x:Name="button3" Content="Button3" Command="{Binding Btn3Command}" CommandParameter="{Binding ElementName=button3}"/>
        </StackPanel>
    </DataTemplate>
    

If it´s another type of event that won't call the command you could use InvokeCommandAction which will be handled same as shown in the next example.

  1. Use a trigger like CallMethodAction (same as above. The DataContext is the place where the method will be searched for.):

    <DataTemplate x:Key="MyTemplate">
        <StackPanel>
            <Button x:Name="button1" Content="Button1" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Tapped">
                        <ei:CallMethodAction MethodName="button1_Tapped"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>...
    
  2. Write a small UserControl as the base for your DataTemplate:

XAML:

<UserControl x:Class="ThreeBtnUserCtrl"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:DataTemplateIssue"
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
       <Button x:Name="button1" Content="Button" Click="button1_Click"/>
       <Button x:Name="button2" Content="Button" Click="button2_Click"/>
       <Button x:Name="button3" Content="Button" Click="button3_Click"/>
    </StackPanel>
</UserControl>

Code behind:

public partial class ThreeBtnUserCtrl : UserControl
{
    public ThreeBtnUserCtrl()
    {
        InitializeComponent();
    }


    private void button1_Click(object sender, RoutedEventArgs e)
    {
        //...some code only controlling view related stuff of your UserCtrl
    }

    private void button2_Click(object sender, RoutedEventArgs e)
    {
        //...some code only controlling view related stuff of your UserCtrl
    }

    private void button3_Click(object sender, RoutedEventArgs e)
    {
        //...some code only controlling view related stuff of your UserCtrl
    }
}

Use it inside your DataTemplate:

<DataTemplate x:Key="MyTemplate">
    <Grid>
        <local:ThreeBtnUserCtrl/>
    </Grid>
</DataTemplate>
Noam M
  • 3,156
  • 5
  • 26
  • 41
SomeUser
  • 36
  • 1
  • Ok, Thx. I tried alternative 1 without success so far. I'll changed the template as you described it. But now I'm not sure how to fill the `Command` and `CpmmandParameters` in the `ListView`. I've tried the following: – Ulpin Apr 04 '16 at 17:00
  • Command="{Binding ElementName=ListviewName,Path=DataContext. Btn1Command}", Assuming Btn1Command is in Listview's datacontext. – Archana Apr 05 '16 at 04:50
  • Sorry guys, I think made a mistake explaining my problem. I tried to explain as easy as possible and have shortened my code by a lot. The event handlers are not set to a `Button ` they are set to various `StackPanels`. And now I cant use the `Command ` property @Archana has posted. – Ulpin Apr 05 '16 at 16:39
  • @Archana Updated my question. The Tap Events to replace are: `Profile_Tapped`, `Content_Tapped`, `Reply_Tapped`, `Favourite_Tapped`, `Retweet_Tapped` – Ulpin Apr 06 '16 at 07:16
  • You still can use this Command="{Binding ElementName=ListviewName,Path=DataContext. Btn1Command}",what exception you are getting? – Archana Apr 06 '16 at 07:22
  • Is it Windows phone 8.1? – Archana Apr 06 '16 at 07:23
  • @Archana Yes WP8.1 There is no command property available for `Stackpanel` or `ListView` – Ulpin Apr 06 '16 at 13:45
  • You can use behaviours – Archana Apr 06 '16 at 13:51
  • Use these namespaces xmlns:interact="using:Microsoft.Xaml.Interactivity" xmlns:interactcore="using:Microsoft.Xaml.Interactions.Core" – Archana Apr 06 '16 at 13:51
  • I have added my answer,check it. Please edit the tag to WIndows phone 8.1 also. – Archana Apr 06 '16 at 14:00
  • @Archana I've added the two namespaces in both XAML files. Then I've added your behavior to the StackPanel in the APP.XAML but the behaviours won't get found in the namspace... – Ulpin Apr 06 '16 at 14:03
  • You have to add Behavioural SDK reference. Go to add reference->Extensions->Behavioural SDK – Archana Apr 06 '16 at 14:04
  • @Archana Ok. reference is working. Will need a few moments to do the rest. looks good so far, – Ulpin Apr 06 '16 at 14:07
  • @Archana Is it right that I have to implement the ICommand interface in my class which I want to bind like it is described [link](http://stackoverflow.com/questions/12422945/how-to-bind-wpf-button-to-a-command-in-viewmodelbase). Still struggeling with the `Command="{Binding DataContext.Btn1Command}'` – Ulpin Apr 06 '16 at 14:34
  • If you use prism framework it's easy. No need to implement ICommand – Archana Apr 06 '16 at 14:59
  • Easiest way is as mentioned in above answer use UserControl approach – Archana Apr 06 '16 at 15:03
  • @Archana Thank You very much. I decided to implement the UserControl. I'll update my Question so future reader will know. I'm now having some trouble retrieving the sender variable in the eventhandler function. If you know what this error is about let me know, but I think it is time to close this post and open eventually a new one. Thanks again for beeing so patient with me :-) – Ulpin Apr 06 '16 at 18:33
1

You can use a Command and EventTrigger and have it bound to your View Model’s command.

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Tapped">
        <i:InvokeCommandAction Command="{Binding TappedCommand}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

Or use a small UserControl insted a DataTemplate:

<UserControl... >
    <StackPanel>
       <Button x:Name="button1" Content="Button" Click="button1_Click"/>
    </StackPanel>
</UserControl>

And use it in your app.xaml:

<DataTemplate x:Key="Template">
    <Grid>
        <local:myUserControl/>
    </Grid>
</DataTemplate>
Noam M
  • 3,156
  • 5
  • 26
  • 41
1

Use Behaviours in stackpanel

<DataTemplate x:Key="GlobalBox">
    <Border Background="#FFFFFFFF" Margin="10 0 0 5" CornerRadius="2 2 15 2">
        <Grid Width="380">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" Tag="{Binding ID}" Name="ProfileInfo" Orientation="Horizontal" Margin="15 15 15 0">
                <Grid Width="360" Margin="0 0 0 10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="75"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="50"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Border Grid.Column="0" Height="45" Width="45" CornerRadius="5">
                        <Border.Background>
                            <ImageBrush ImageSource="{Binding ImagePath}" Stretch="UniformToFill"/>
                        </Border.Background>
                    </Border>
                    <StackPanel Grid.Column="1" Orientation="Vertical" Margin="0 5 0 0">
                        <TextBlock Text="{Binding Name}" Foreground="Black" FontSize="18" FontWeight="Bold"></TextBlock>
                        <TextBlock Text="{Binding Handle}" Foreground="DarkGray" FontSize="12"/>
                    </StackPanel>
                    <Image Grid.Column="2" Source="Assets/ActionIcons/logo_blue_32.png" Width="32" VerticalAlignment="Top"></Image>
                </Grid>
                <interact:Interaction.Behaviors>
                    <interactcore:EventTriggerBehavior EventName="Tapped" >
                        <interactcore:InvokeCommandAction Command="{Binding Path=DataContext.Btn1Command}" />
                    </interactcore:EventTriggerBehavior>
                </interact:Interaction.Behaviors>
            </StackPanel>

        </Grid>
    </Border>
</DataTemplate>
Noam M
  • 3,156
  • 5
  • 26
  • 41
Archana
  • 3,213
  • 1
  • 15
  • 21
  • This worked but caused me more additional work in the code-behind than using the Usercontrol so I've went the other way. Thanks! – Ulpin Apr 06 '16 at 18:34