Developer
Developer

Reputation: 4341

XAML Buttons in ListBoxItem template

I have a ListBox that has a single select. When item is selected it should show additional options like - edit, delete buttons.

So i have done this:

<ListBox ItemContainerStyle="{StaticResource MyItemStyle}" Loaded="MyList_Loaded">

</ListBox>

And here is my template:

<Style x:Key="MyItemStyle" TargetType="ListBoxItem">
        <!--Deleted to minimize the snippet-->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Grid x:Name="LayoutRoot" BorderThickness="0,1,0,0" BorderBrush="Black" Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <!--Deleted to minimize the snippet-->
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EditButtons">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <!--Deleted to minimize the snippet-->
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Rectangle x:Name="PressedBackground" Grid.RowSpan="2" Fill="Transparent" Control.IsTemplateFocusTarget="True"/>
                        <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="Stretch" Style="{StaticResource BodyContentPresenterStyle}" TextWrapping="NoWrap" VerticalAlignment="Stretch"/>
                        <Grid Grid.Row="1" HorizontalAlignment="Right" Margin="13,0,13,13" Visibility="Collapsed" x:Name="EditButtons">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto"/>
                                <ColumnDefinition Width="auto"/>
                                <ColumnDefinition Width="auto"/>
                            </Grid.ColumnDefinitions>
                            <HyperlinkButton 
                                x:Name="SendButton" 
                                VerticalAlignment="Center"
                                IsTabStop="True"
                                TabIndex="3"
                                Margin="7,0,0,0"
                                Content="Send" 
                                Style="{StaticResource HyperlinksStyle}" 
                                />
                            <HyperlinkButton 
                                x:Name="EditButton" 
                                VerticalAlignment="Center"
                                IsTabStop="True"
                                TabIndex="3"
                                Grid.Column="1"
                                Margin="7,0,0,0"
                                Content="Edit" 
                                Style="{StaticResource HyperlinksStyle}" 
                                />
                            <HyperlinkButton 
                                x:Name="DeleteButton" 
                                VerticalAlignment="Center"
                                IsTabStop="True"
                                TabIndex="3"
                                Grid.Column="2"
                                Margin="7,0,0,0"
                                Content="Delete" 
                                Style="{StaticResource HyperlinksStyle}" 
                                />
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

I cant figure out how can i bind Click handlers to those 3 hyperlink buttons. I have tried to:

private void MyList_Loaded(object sender, RoutedEventArgs e)
{
    var sendButton = FindChild<HyperlinkButton>(MyList, "SendButton");
}

And

Adding a handler directly in XAML from visual editor.

But all this didn't work. How can i react to click events of those 3 buttons?

Upvotes: 0

Views: 1560

Answers (3)

Blackstar
Blackstar

Reputation: 161

You have to implement the grid with buttons to hide in the listbox's ItemTemplate and click events will be fired.

<Page
...
xmlns:converter="using:VisibilyConverter" 
...
>

<Grid x:Name="LayoutRoot">
    <Grid.Resources>
       <converter:VisibiliyConverter x:Key="visibilityConverter" />
    </Grid.Resources>
    <ListBox>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Grid.Row="1" HorizontalAlignment="Right" Margin="13,0,13,13" Visibility="{Bindig IsSelected, Mode=OneWay,
                            Converter={StaticResource visibilityConverter}}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="auto"/>
                    <ColumnDefinition Width="auto"/>
                    <ColumnDefinition Width="auto"/>
                </Grid.ColumnDefinitions>
                <HyperlinkButton 
                    x:Name="SendButton" 
                    VerticalAlignment="Center"
                    IsTabStop="True"
                    TabIndex="3"
                    Margin="7,0,0,0"
                    Content="Send" 
                    Style="{StaticResource HyperlinksStyle}" 
                    Click="SendButtonClick
                    />
                <HyperlinkButton 
                    x:Name="EditButton" 
                    VerticalAlignment="Center"
                    IsTabStop="True"
                    TabIndex="3"
                    Grid.Column="1"
                    Margin="7,0,0,0"
                    Content="Edit" 
                    Style="{StaticResource HyperlinksStyle}" 
                    Click="EditButtonClick
                    />
                <HyperlinkButton 
                    x:Name="DeleteButton" 
                    VerticalAlignment="Center"
                    IsTabStop="True"
                    TabIndex="3"
                    Grid.Column="2"
                    Margin="7,0,0,0"
                    Content="Delete" 
                    Style="{StaticResource HyperlinksStyle}" 
                    Click="DeleteButtonClick
                    />
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>


void SendButtonClick(object sender, RoutedEventArgs e)
{
    ...
}

void DeleteButtonClick(object sender, RoutedEventArgs e)
{
    ...
}

Upvotes: 0

Andrii Krupka
Andrii Krupka

Reputation: 4306

So, install MvvmLightLibs nuget package, and create command in your code-behind

public RelayCommand<MyClassModel> SendCommand { get; set; }

Initialize in ctor:

public MainPage()
{
    this.InitializeComponent();
    SendCommand = new RelayCommand<MyClassModel>(SendExecute);
    DataContext = this;
}

and execute callback:

private void SendExecute(MyClassModel item)
{

}

In XAML code setup name to ListBox and bind your command

<ListBox ItemContainerStyle="{StaticResource MyItemStyle}"
         x:Name="listBox"/>

<HyperlinkButton x:Name="SendButton" 
                    VerticalAlignment="Center"
                    Command="{Binding DataContext.SendCommand, ElementName=listBox}"
                    CommandParameter="{Binding }"
                    IsTabStop="True"
                    TabIndex="3"
                    Margin="7,0,0,0"
                    Content="Send"/>

Upvotes: 0

makzr
makzr

Reputation: 355

When the Template/Style is defined in the same XAML file as the button you can easily use the Click Handler in XAML:

<HyperlinkButton x:Name="SendButton" 
    VerticalAlignment="Center"
    IsTabStop="True"
    TabIndex="3"
    Margin="7,0,0,0"
    Content="Send" 
    Style="{StaticResource HyperlinksStyle}" 
    Click="HandleSendClick"
    />

private void HandleSendClick(object sender, RoutedEventArgs e)
{
    //...
}

However, I would recommend you to use MVVM and Command Bindings in general. Using event handlers in WPF is archaic.

Upvotes: 1

Related Questions