Xaml 在UWP中,如何使用可隐藏内容正确自定义ListViewItem并将其绑定到模型?

Xaml 在UWP中,如何使用可隐藏内容正确自定义ListViewItem并将其绑定到模型?,xaml,uwp,model-binding,uwp-xaml,Xaml,Uwp,Model Binding,Uwp Xaml,我想创建一个列表视图,其中项目具有“悬停”和“选定”状态,在每个状态下显示不同的内容 关于StackOverflow,这里也有一些类似的问题,但在我的特定案例中,没有一个能起到作用 假设我有一个模型: …然后我有一个主视图模型: 公共类AppViewModel:BaseBind { 公共ObservableCollection项列表{get;set;} //其他事情 } 。。。然后是一页: 我想自定义ListViewItem样式,以便使SelectButton仅在选中ListViewIte

我想创建一个列表视图,其中项目具有“悬停”和“选定”状态,在每个状态下显示不同的内容

关于StackOverflow,这里也有一些类似的问题,但在我的特定案例中,没有一个能起到作用

假设我有一个模型:

…然后我有一个主视图模型:

公共类AppViewModel:BaseBind
{
公共ObservableCollection项列表{get;set;}
//其他事情
}
。。。然后是一页:


我想自定义ListViewItem样式,以便使SelectButton仅在选中ListViewItem时显示,而HoverButton仅在光标位于其上时显示

我已经知道我需要使用ItemTemplate和ItemContainerStyle,但这似乎比我一开始想象的要困难,因为我可以用这种方式(使用ListViewItem中的IsSelected属性)为ItemContainerStyle创建自定义样式:


…但这样做: 1) 我松开了所有默认笔刷; 2) 我不知道如何将SelectButton绑定到模型的命令; 3) 我必须找到一种“悬停”状态的方法,以便显示悬停按钮; 4) 最后,但并非最不重要。。。我希望在App.xaml文件(或相关的ResourceDictionary文件,因为我需要在整个应用程序中包含这些自定义项)中包含所有自定义项

就是这样。。。我尝试了StackOverflow答案中的各种模式,但我的案例包括许多不同的内容(在App.xaml文件中编译绑定、创建“悬停”状态、以没有数据类型的样式使用绑定等),这些内容在这里仅单独回答

我需要。。。把它们放在一起,就像我说的,看起来比我想象的要复杂

谢谢你的帮助,非常感谢

编辑:行为应类似于Groove应用程序列表项目:某些按钮(播放和删除项目)仅在项目被选中或处于悬停状态时显示

正常状态:

…和悬停/选定状态:


有两种方法可以实现您的目标:

第一个:我不喜欢它,因为您需要复制整个样式并将项目模板嵌入样式中。如果你想在应用程序的多个部分有相同的行为,它也不会伸缩

您可以复制使用UIElement树和可视状态而不是ListViewItemPresenter的。这样就不会丢失默认笔刷

注意:在上面的链接中查找带有
x:Key=“ListViewItemExpanded”
的模板

Xaml:



我想我可以提供部分帮助。我本人以前从未尝试过以某种方式进行数据绑定,所以希望我们都能学到一些东西。您可以将控件输入绑定到viewmodel方法,而不是使用事件。只需单击一个按钮,就可以使用ICommand界面。对于更高级的输入,如鼠标悬停,您需要使用。根据我在XAML中的经验(尽管非常有限),如果您想保留画笔等,样式模板不需要包含默认模板的所有内容吗?@SeanO'Neil,ListViewItem的默认样式包含ListViewItemPresenter,这很难处理。。。也许,它甚至不是正确的,因为我正在搜索ItemContainerStyle的默认样式,而不是ListViewItem样式…猜猜怎么着?今天我自己才想出了这个解决办法!无论如何谢谢你。
public class TagFile : BaseBind // A class with INotifyProperyChanged interface
{
    private string path;
    public String Path
    {
        get { return path; }
        set
        {
            SetProperty(ref path, value);
        }
    }

    public void SelectButtonClick() 
    {
        // Do something
    }

    public void HoverButtonClick() 
    {
        // Do something
    }
}
public class AppViewModel : BaseBind
{
    public ObservableCollection<TagFile> ItemsList { get; set; }

    // Other things
}
<Grid>
     <ListView ItemsSource="ItemsList">
          <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:TagFile">
                     <Grid>
                          <Grid.RowDefinitions>
                              <RowDefinition/>
                              <RowDefinition/>
                              <RowDefinition/>
                          </Grid.RowDefinitions>
                          <TextBlock Text="{x:Bind Path, mode=OneWay}"/>
                          <Button Content="Select Button" Click="{x:Bind SelectButtonClick}"/> 
                          <Button Content="Hover Button" Click="{x:Bind HoverbuttonClick}"/>
                     </Grid>
                </DataTemplate>
          </ListView.ItemTemplate>
     </ListView>
</Grid>
<Style TargetType="ListViewItem" x:Key="TestContainerStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListViewItem">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <ContentPresenter x:Name="Presenter" Content="{TemplateBinding Content}"/>
                        <Button Grid.Row="1" Content="Select Button" Visibility="{Binding IsSelected, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    </Style>
<!-- Style for Windows.UI.Xaml.Controls.ListViewItem -->
<Style TargetType="ListViewItem" x:Key="ListViewItemExpanded">
public class ExtendedControl : ContentControl
    {
        public static readonly DependencyProperty IsPointerOverProperty =
            DependencyProperty.Register("IsPointerOver", typeof(bool), typeof(ExtendedControl),
                new PropertyMetadata(false));

        public bool IsPointerOver
        {
            get => (bool)GetValue(IsPointerOverProperty);
            protected set => SetValue(IsPointerOverProperty, value);
        }
        protected override void OnPointerEntered(PointerRoutedEventArgs e)
        {
            base.OnPointerEntered(e);
            IsPointerOver = true;
        }
        protected override void OnPointerCanceled(PointerRoutedEventArgs e)
        {
            base.OnPointerCanceled(e);
            IsPointerOver = false;
        }
        protected override void OnPointerExited(PointerRoutedEventArgs e)
        {
            base.OnPointerExited(e);
            IsPointerOver = false;
        }
    }
  <ListView.ItemTemplate>
            <DataTemplate >
                <local:ExtendedControl x:Name="ExtendedControl">
                    <StackPanel>
                        <Button Content="Always Visible"/>
                        <Button Content="Only on hover" Visibility="{x:Bind ExtendedControl.IsPointerOver,Mode=OneWay,Converter={StaticResource BoolToVisibilityConverter}}"/>
                    </StackPanel>
                </local:ExtendedControl>
            </DataTemplate>
        </ListView.ItemTemplate>