Antoine
Antoine

Reputation: 312

Button inside listview c#

I've successfully put a button inside each listview item. But I want to obtain the Item on which the button is.. In this case each item is a Friend and has a button on click of the button I want to now which friend it is. How can I achieve this?

VIEW

 <ListView x:Name="dataGrid" ItemsSource="{Binding Friends}" Height="314" BorderThickness="0" SelectedItem="{Binding SelectedItemFriends}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Image Source="Resources\Images\ic_status.png" Height="24" Width="18"/>
                    <StackPanel Margin="5" Orientation="Vertical">
                            <TextBlock FontWeight="Bold" Text="{Binding name}"/>                                
                        <StackPanel x:Name="RemoveItems" Margin="5" Orientation="Vertical">
                            <TextBlock Text="{Binding lastLocation}"/>
                            <TextBlock Text="{Binding timestamp}"/>
                        </StackPanel>
                        <StackPanel x:Name="AdditionItems" Margin="5" Orientation="Vertical" Visibility="Collapsed">
                            <TextBlock Text="{Binding Path=loc.area}"/>
                            <TextBlock Text="{Binding Path=loc.building}"/>
                            <TextBlock Text="{Binding Path=loc.floor}"/>
                            <TextBlock Text="{Binding Path=loc.room}"/>
                        </StackPanel>
                    </StackPanel>
                    <Button Style="{DynamicResource FlatButtonStyle}" Command="{Binding DataContext.SelectViewCommand, ElementName=GeneralWindowView}"  CommandParameter="ChatViewModel"  x:Name="button1" Content="Chat" Margin="10">
                        <Button.Template>
                            <ControlTemplate>
                                <Image Source="Resources\Images\chat_image.png"/>
                            </ControlTemplate>
                        </Button.Template>
                    </Button>
                </StackPanel>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" Value="true">
                        <Setter TargetName="AdditionItems" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="RemoveItems" Property="Visibility" Value="Collapsed"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

Best regards, Antoine

Upvotes: 0

Views: 2014

Answers (2)

User9995555
User9995555

Reputation: 1556

You could do something like this....

class Friend
{
    // Other properties......
    public string Link_1 { get; set; }
}

set Link_1 = "ChatViewModel" somewhere

XAML

<Button x:Name="button1" Command="{Binding DataContext.SelectViewCommand, ElementName=GeneralWindowView}" CommandParameter="{Binding}">

then in your SelectViewCommand Command handler

public void OnSelectViewCommand (dynamic obj)
{
    this.Current_ViewModel = this.GetViewModel(obj.Link_1);
}

EDIT........

There is another way that directly addresses the issue of sending multiple parameters in the CommandParameter...

XAML

add the manespace

xmlns:Converters="clr-namespace:CommandParameterExample.Converters"

add the Resource

<UserControl.Resources>
    <Converters:CommandParameter_Converter x:Key="CommandParameter_Converter" />
</UserControl.Resources>

Add a hidden Text Block

<TextBlock Visibility="Collapsed" Name="VM" Text="ChatViewModel"></TextBlock>

Here is your Button

<Button Content="Chat" Command="{Binding DataContext.SelectViewCommand, ElementName=GeneralWindowView}" >
    <Button.CommandParameter>
        <MultiBinding Converter="{StaticResource CommandParameter_Converter}">
            <Binding/>
            <Binding Path="Text" ElementName="VM"/>
        </MultiBinding>
    </Button.CommandParameter>
</Button>

Here is the CommandParameter_Converter

class CommandParameter_Converter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values.Clone(); // simply return an array
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

and here is your SelectViewCommand

public void OnSelectViewCommand (object parameter)
{
    var values = (object[])parameter;
    var FriendObject = (dynamic)values[0];
    var ViewModelName = (string)values[1];
}

This is the correct way to resolve your issue (sending 2 arguments in CommandParameter). But as you can see, it's rather involved....

Upvotes: 1

Massimiliano Kraus
Massimiliano Kraus

Reputation: 3835

You can bind the CommandParameter to the ListViewItem to which the Button belongs. Something like:

<Button x:Name="button1"
        Command="{Binding DataContext.SelectViewCommand,
          ElementName=GeneralWindowView}"
        CommandParameter="{Binding}">

In this way, the CommandParameter is always the ViewModel of the ListViewItem on which the Button stays.

As a side node, I think that if the SelectViewCommand deals with the current ListViewItem, maybe the Command should stay on the ViewModel of the ListViewItem, not the one on the GeneralWindowView...

Any way, hope this helps.

Upvotes: 3

Related Questions