【问题标题】:how to make ListView nonselectable, width like "*", and use DataTemplate如何使 ListView 不可选择,宽度如“*”,并使用 DataTemplate
【发布时间】:2014-10-24 09:23:10
【问题描述】:

我正在学习使用ListView列出多列的数据(即第1列是文件名,第2列是页数等),遇到了几个问题:

  1. 下面的代码显示了 2 列,其中列宽由 <GridViewColumn Width="Auto"> 指定。如何指定列以使用所有可用宽度?我尝试将Width="*" 设置为Grid,但这会产生错误。

  2. 如何使ListView 不可选择?我看到this post 使ListBox 不可选择,但类似的方法不适用于ListView(显示在代码中)。

更新:解决了问题 #2。见代码。

  1. 您能否展示一个使用DataTemplateListView 的简单示例?我只想在 MainWindow 中添加类似 <ListView ItemsSource="{Binding }" ItemTemplate="{StaticResource myTemplate}"/> 的内容,以便保持干净。

(4.ish。我从this post学到了下面的代码。如果有更简单的方法,请告诉我。)

谢谢!

<ListView HorizontalContentAlignment="Stretch" Grid.Row="0" ItemsSource="{Binding }">

    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="Focusable" Value="False"/>   <--- disable selection
        </Style>
    </ListView.ItemContainerStyle>

    <ListView.View>
        <GridView>
            <GridViewColumn Width="Auto">
                <GridViewColumnHeader Content="Filename"/>
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Filename}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>

            <GridViewColumn Width="Auto">
                <GridViewColumnHeader Content="Pages"/>
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Pages}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>

        </GridView>
    </ListView.View>
<ListView>

【问题讨论】:

    标签: wpf xaml listview


    【解决方案1】:

    我不确定是否有任何其他直接的解决方案(尽管我几乎可以肯定没有任何直接的方法)。以下解决方案可以被视为一种解决方法,但它实际上是一个漂亮的解决方案。

    您可以使用一些Binding 将ListView 的列宽度绑定到Grid 的列宽度,使第二列(或通常是最后一列)填充剩余空间。是的,我们知道只有Grid 有一些其他控件没有的功能。以下是详细步骤:

    • 首先,我们需要一个与 ListView 具有相同列数的Grid。 ListView 当然应该放在这个Grid 里面。通过使用Grid.ColumnSpan,我们可以让ListView填满整个Grid。
    • 其次,将所有Grid列的Width绑定到对应ListView列除了最后一个Column的ActualWidth。 Grid 的最后一列应将Width 设置为*(填充剩余空间)。
    • 最后,您需要在网格的最后一列中放置一些虚拟元素(例如边框)。我们需要这个虚拟元素来获取它的ActualWidth,以便我们可以将最后一个ListView 列的宽度绑定到那个ActualWidth。 Grid 的ColumnDefinition 也有属性ActualWidth 但是它不是依赖属性并且它也没有任何属性更改通知机制(因此我们不能使用该属性)。

    现在是工作代码:

    <Grid Grid.Row="0">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{Binding ActualWidth,ElementName=firstCol}"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <!-- the dummy element -->
      <Border Grid.Column="1" Name="dummy" Margin="5"></Border>
      <ListView HorizontalContentAlignment="Stretch" Grid.ColumnSpan="2"
              ItemsSource="{Binding }">
    
         <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
              <Setter Property="Focusable" Value="False"/>
            </Style>
         </ListView.ItemContainerStyle>
    
         <ListView.View>
            <GridView>
              <GridViewColumn Width="Auto" x:Name="firstCol">
                  <GridViewColumnHeader Content="Filename"/>
                  <GridViewColumn.CellTemplate>
                      <DataTemplate>
                        <TextBlock Text="{Binding Path=Filename}"/>
                      </DataTemplate>
                  </GridViewColumn.CellTemplate>
               </GridViewColumn>
    
               <GridViewColumn Width="{Binding ActualWidth, ElementName=dummy}">
                  <GridViewColumnHeader Content="Pages"/>
                  <GridViewColumn.CellTemplate>
                      <DataTemplate>
                        <TextBlock Text="{Binding Path=Pages}"/>
                      </DataTemplate>
                  </GridViewColumn.CellTemplate>
               </GridViewColumn>
    
            </GridView>
          </ListView.View>
      <ListView>
    </Grid>
    

    请注意,您的原始ListView 可能会放置在某个网格中(您设置了它的Grid.Row="0")。然而,当使用这个技巧时,ListView 应该总是放在一个包装器 Grid 并且你必须为这个包装器 Grid 设置 Grid.Row="0"(尽管这是默认设置)。我的意思是这个包装网格将被放置在你原来的Grid(如果有的话)中。

    更新:要让它像Grid 一样动态,您需要更多的虚拟元素(我们在上面的代码中的最后一列只使用了 1 个虚拟边框)。每个虚拟元素将被放入每个 Grid 的列中。正如我所解释的,我们需要它来代理 Grid 列的 ActualWidth,虽然 ColumnDefinition 也有一个 ActualWidth 属性,但它不能在 Binding 中使用(不支持任何更改通知)。代码如下:

    <Grid Grid.Row="0">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="2*"/>
      </Grid.ColumnDefinitions>
      <!-- the dummy elements -->
      <Border Grid.Column="0" Name="dummy1" Margin="5"></Border>
      <Border Grid.Column="1" Name="dummy2" Margin="5"></Border>
      <!-- your ListView -->
      <ListView HorizontalContentAlignment="Stretch" Grid.ColumnSpan="2"
              ItemsSource="{Binding }">
    
         <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
              <Setter Property="Focusable" Value="False"/>
            </Style>
         </ListView.ItemContainerStyle>
    
         <ListView.View>
            <GridView>
              <GridViewColumn Width="{Binding ActualWidth, ElementName=dummy1}">
                  <GridViewColumnHeader Content="Filename"/>
                  <GridViewColumn.CellTemplate>
                      <DataTemplate>
                        <TextBlock Text="{Binding Path=Filename}"/>
                      </DataTemplate>
                  </GridViewColumn.CellTemplate>
               </GridViewColumn>
    
               <GridViewColumn Width="{Binding ActualWidth, ElementName=dummy2}">
                  <GridViewColumnHeader Content="Pages"/>
                  <GridViewColumn.CellTemplate>
                      <DataTemplate>
                        <TextBlock Text="{Binding Path=Pages}"/>
                      </DataTemplate>
                  </GridViewColumn.CellTemplate>
               </GridViewColumn>
    
            </GridView>
          </ListView.View>
      <ListView>
    </Grid>
    

    【讨论】:

    • 感谢您的回答!此解决方案将所有剩余宽度提供给最后一列;是否可以根据预定义的比率分配宽度?比如“2*”和“*”?
    • @green 这个想法是一样的,我们只需要稍微调整一下,详情见我的更新。
    • 确实很漂亮!现在,我怎样才能多次投票? ;)
    • @green 接受答案对我来说已经足够了 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 2011-10-04
    • 1970-01-01
    相关资源
    最近更新 更多