ListViewItem不选择按钮单击

时间:2011-10-03 12:50:30

标签: wpf listview mvvm selection

我有一个ListView,其中ListView项目有按钮和文本块....

Senario:

我可以单击按钮而不选择ListView项目,即选择最后一项,然后如果我尝试单击第一项的按钮,则第一次没有被选中(在DataGrid中它确实选择)。

我不能使用DataGrid,因为我在ListView中使用CustomView。

如果你需要我的代码参考问题,我会发布它..

在这方面的任何帮助都会很棒

My ListView :  

  <ListView Name="lv"
              Grid.Row="1"
              DisplayMemberPath="Name"
              IsTextSearchEnabled="True"
              ItemsSource="{Binding}"
              KeyboardNavigation.DirectionalNavigation="Cycle"
              SelectionMode="Single"
              TextSearch.TextPath="{Binding Path=Person.Name}"
              View="{Binding Path=SelectedItem,
                             ElementName=viewComboBox}" />

我的CustomViews DataTemplates:

 <Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type CustomView:PlainView},
                                    ResourceId=ImageView}"
       BasedOn="{StaticResource {x:Type ListBox}}"
       TargetType="{x:Type ListView}">
    <Setter Property="BorderBrush" Value="Black" />
    <Setter Property="BorderThickness" Value=".5" />
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="ItemContainerStyle" Value="{Binding (ListView.View).ItemContainerStyle, RelativeSource={RelativeSource Self}}" />
    <Setter Property="ItemTemplate" Value="{Binding (ListView.View).ItemTemplate, RelativeSource={RelativeSource Self}}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Border Name="bd"
                        Margin="{TemplateBinding Margin}"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <ScrollViewer Margin="{TemplateBinding Padding}">
                        <WrapPanel KeyboardNavigation.DirectionalNavigation="Cycle" 
                                   Width="{Binding ActualWidth,
                                                   RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
                                   MinWidth="{Binding (ListView.View).MinWidth,
                                                      RelativeSource={RelativeSource Mode=FindAncestor,
                                                                                     AncestorType={x:Type ListView}}}"
                                   IsItemsHost="True"
                                   ItemWidth="{Binding (ListView.View).ItemWidth,
                                                       RelativeSource={RelativeSource Mode=FindAncestor,
                                                                                      AncestorType={x:Type ListView}}}" Orientation="Vertical"
                                   Height="{Binding ActualHeight,
                                                   RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"/>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type CustomView:PlainView},
                                    ResourceId=ImageViewItem}"
       BasedOn="{StaticResource {x:Type ListBoxItem}}"
       TargetType="{x:Type ListViewItem}">
    <Setter Property="Padding" Value="3" />
    <Setter Property="Margin" Value="5" />
    <Setter Property="BorderBrush" Value="Black" />
    <Setter Property="BorderThickness" Value="2" />
    <Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>

<DataTemplate x:Key="centralTile">
    <StackPanel Width="80" Height="40" KeyboardNavigation.AcceptsReturn="True">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="30"></ColumnDefinition>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Button x:Name="tempabc" Command="{Binding Path=Launch}" KeyboardNavigation.AcceptsReturn="True" >
                <TextBlock Text="{Binding Path=Name}" FocusManager.IsFocusScope="True"></TextBlock>
            </Button>
            <Image Grid.Column="1" Source="Water lilies.jpg"/>
        </Grid>
        <TextBlock
                           HorizontalAlignment="Center"
                           FontSize="13"
                           Text="{Binding Path=Name}" />
    </StackPanel>
</DataTemplate>
<CustomView:PlainView x:Key="plainView"
                              ItemTemplate="{StaticResource ResourceKey=centralTile}"
                              ItemWidth="100" />  
<GridView x:Key="myGridView">
        <GridViewColumn>
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <Button>
                        <TextBlock Text="{Binding Path=Name}" />
                    </Button>
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
    </GridView>

1 个答案:

答案 0 :(得分:3)

与大多数事情一样,有很多方法可以做到这一点。这是我一分钟就把它扔在一起......

鉴于以下模型:

public sealed class ItemModel
{
    public string Name { get; set; }
}

我希望向用户显示它们的集合,并通过按钮选择一个。这意味着我在ViewModel中需要三件事:

  1. ItemModels的集合
  2. 用于保存当前所选实例的“SelectedItem”属性
  3. 用于绑定到View
  4. 中按钮的ICommand实现

    我创建了我的ViewModel并将这些项添加到其中。请注意,我更喜欢让我的ViewModel扩展DependencyObject而不是乱用INPC。

    public sealed class ViewModel : DependencyObject
    {
        // 1. A collection of ItemModels
        public ObservableCollection<ItemModel> ItemModels { get; private set; }
        // 2. A "SelectedItem" property to hold the currently selected instance
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register(
                "SelectedItem",
                typeof(ItemModel),
                typeof(ViewModel),
                new UIPropertyMetadata(null));
        public ItemModel SelectedItem
        {
            get { return (ItemModel)GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }
        // 3. An ICommand implementation to bind to the buttons in the View
        public Command SelectItem { get; private set; }
        public ViewModel()
        {
            ItemModels = new ObservableCollection<ItemModel>();
            ItemModels.Add(new ItemModel { Name = "One" });
            ItemModels.Add(new ItemModel { Name = "Two" });
            ItemModels.Add(new ItemModel { Name = "Three" });
            SelectItem = new Command 
            { 
                ExecuteAction = x => SelectedItem = x as ItemModel 
            };
        }
    }
    

    最后,我将我的UI与一个基本的ListView拼凑在一起。

    <Window
        x:Class="q_7635202.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="WindowRoot">
        <ListView
            SelectedItem="{Binding SelectedItem}"
            ItemsSource="{Binding ItemModels}">
            <ListView.View>
                <GridView>
                    <GridViewColumn
                        DisplayMemberBinding="{Binding Name}"
                        Header="Name" /> 
                    <GridViewColumn>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button
                                    Content="Select"
                                    Command="{Binding DataContext.SelectItem,
                                                      ElementName=WindowRoot}"
                                    CommandParameter="{Binding}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
    </Window>
    

    这一切都很直接。我放弃了ICommand的实现,因为它很简单。