1

我目前正在处理的 UWP 项目有问题:

我有一个这样的视图模型:

public class HomePageViewModel : INotifyPropertyChanged
{
     public event PropertyChangedEventHandler PropertyChanged;

      public ObservableCollection<WidgetViewModel> Widgets { get; } = new ObservableCollection<WidgetViewModel>();

      public HomePageViewModel()
      {
      }

      public void OnNotifyPropertyChanged([CallerMemberName]string propertyName = "")
      {
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }
}

WidgetViewModel 的定义如下:

public class WidgetViewModel : INotifyPropertyChanged
{
      private string group;

      public string Group
      {
           get=>group;
           set
           {
                 group=value;
                 OnNotifyPropertyChanged();
           }
      }

      public event PropertyChangedEventHandler PropertyChanged;

      public ObservableCollection<ItemViewModel> Items { get; } = new ObservableCollection<ItemViewModel>();

      public WidgetPageViewModel()
      {
      }

      public void OnNotifyPropertyChanged([CallerMemberName]string propertyName = "")
      {
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }
}

我的 ItemViewModel 是这样定义的:

public class ItemViewModel : INotifyPropertyChanged
{
      private string name;

      public event PropertyChangedEventHandler PropertyChanged;

      public string Name
      {
         get=>name;
         set
         {
            name = value;
            OnNotifyPropertyChanged();
         }
      }

      public ItemViewModel()
      {
      }

      public void OnNotifyPropertyChanged([CallerMemberName]string propertyName = "")
      {
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }
}

我制作了这个 xaml :

<Page x:Class="Project.TestPage"
                       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                       
                       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                       xmlns:local="Project"
                       Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
                       mc:Ignorable="d">
    <Grid>
        <Grid.Resources>
            <CollectionViewSource x:Name="TestSource"
                                  IsSourceGrouped="True"
                                  Source="{Binding Widgets}" />
            <local:ItemTemplateSelector x:Key="ItemTemplateSelector">
                    <local:ItemTemplateSelector.WidgetTemplate>
                          <DataTemplate>
                              <local:TestItemsControl ItemTemplateSelector="{StaticResource ItemTemplateSelector}"
                                            ItemsSource="{Binding Items}">
                                  <local:TestItemsControl.ItemContainerStyle>
                                     <Style TargetType="local:TestItem">
                                          <Setter Property="HorizontalAlignment" Value="Stretch" />
                                          <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                                          <Setter Property="VerticalAlignment" Value="Stretch" />
                                          <Setter Property="VerticalContentAlignment" Value="Stretch" />
                                     </Style>
                                  </local:TestItemsControl.ItemContainerStyle>
                              </local:TestItemsControl>
                          </DataTemplate>
                    </local:ItemTemplateSelector.WidgetTemplate>
                    <local:ItemTemplateSelector.ItemTemplate>
                          <DataTemplate>
                              <TextBlock Text="{Binding Name}" />
                          </DataTemplate>
                    </local:ItemTemplateSelector.ItemTemplate>
            </local:ItemTemplateSelector>
            <x:String x:Key="ChevronGlyph">&#xE26B;</x:String>

            <Style x:Key="TextButtonStyle" TargetType="ButtonBase">
                <Setter Property="MinWidth" Value="0" />
                <Setter Property="MinHeight" Value="0" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ButtonBase">
                            <Grid Background="Transparent">
                                <ContentPresenter x:Name="Text" Content="{TemplateBinding Content}" />
                                <Rectangle x:Name="FocusVisualWhite"
                                           IsHitTestVisible="False"
                                           Opacity="0"
                                           Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
                                           StrokeDashArray="1,1"
                                           StrokeDashOffset="1.5"
                                           StrokeEndLineCap="Square" />
                                <Rectangle x:Name="FocusVisualBlack"
                                           IsHitTestVisible="False"
                                           Opacity="0"
                                           Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
                                           StrokeDashArray="1,1"
                                           StrokeDashOffset="0.5"
                                           StrokeEndLineCap="Square" />
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal" />
                                        <VisualState x:Name="PointerOver">
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}" />
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Pressed">
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}" />
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}" />
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                    <VisualStateGroup x:Name="FocusStates">
                                        <VisualState x:Name="Focused">
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetName="FocusVisualWhite"
                                                                 Storyboard.TargetProperty="Opacity"
                                                                 To="1"
                                                                 Duration="0" />
                                                <DoubleAnimation Storyboard.TargetName="FocusVisualBlack"
                                                                 Storyboard.TargetProperty="Opacity"
                                                                 To="1"
                                                                 Duration="0" />
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Unfocused" />
                                    </VisualStateGroup>
                                    <VisualStateGroup x:Name="CheckStates">
                                        <VisualState x:Name="Checked" />
                                        <VisualState x:Name="Unchecked">
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}" />
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Indeterminate" />
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

            <Style x:Key="TextPrimaryButtonStyle"
                   BasedOn="{StaticResource TextButtonStyle}"
                   TargetType="ButtonBase">
                <Setter Property="Foreground" Value="{StaticResource ApplicationHeaderForegroundThemeBrush}" />
            </Style>

            <Style x:Key="GroupHeaderTextStyle" TargetType="TextBlock">
                <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}" />
                <Setter Property="TextTrimming" Value="WordEllipsis" />
                <Setter Property="TextWrapping" Value="NoWrap" />
                <Setter Property="Typography.StylisticSet20" Value="True" />
                <Setter Property="Typography.DiscretionaryLigatures" Value="True" />
                <Setter Property="Typography.CaseSensitiveForms" Value="True" />
                <Setter Property="FontSize" Value="26.667" />
                <Setter Property="LineStackingStrategy" Value="BlockLineHeight" />
                <Setter Property="FontWeight" Value="Light" />
                <Setter Property="LineHeight" Value="30" />
                <Setter Property="RenderTransform">
                    <Setter.Value>
                        <TranslateTransform X="-1" Y="6" />
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <GridView Grid.Row="1"
                  Padding="116,137,40,46"
                  IsItemClickEnabled="False"
                  ItemTemplateSelector="{StaticResource ItemTemplateSelector}"
                  ItemsSource="{Binding Source={StaticResource TestSource}}"
                  ScrollViewer.HorizontalScrollBarVisibility="Auto"
                  ScrollViewer.HorizontalScrollMode="Enabled"
                  ScrollViewer.VerticalScrollBarVisibility="Disabled"
                  ScrollViewer.VerticalScrollMode="Disabled">
            <GridView.ItemContainerStyle>
                <Style TargetType="GridViewItem">
                    <Setter Property="HorizontalAlignment" Value="Stretch" />
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                    <Setter Property="VerticalAlignment" Value="Stretch" />
                    <Setter Property="VerticalContentAlignment" Value="Stretch" />
                </Style>
            </GridView.ItemContainerStyle>
            <GridView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <Button AutomationProperties.Name="Group Title" Style="{StaticResource TextPrimaryButtonStyle}">
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Margin="3,-7,10,10"
                                               Style="{StaticResource GroupHeaderTextStyle}"
                                               Text="{Binding Key}" />
                                    <TextBlock Margin="0,-7,0,10"
                                               FontFamily="Segoe UI Symbol"
                                               Style="{StaticResource GroupHeaderTextStyle}"
                                               Text="{StaticResource ChevronGlyph}" />
                                </StackPanel>
                            </Button>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <VariableSizedWrapGrid Margin="0,0,80,0"
                                                   ItemHeight="200"
                                                   ItemWidth="200"
                                                   Orientation="Vertical" />
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>
                </GroupStyle>
            </GridView.GroupStyle>
            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
        </GridView>
    </Grid>
</Page>

ItemTemplateSelector 的定义如下:

public sealed class ItemTemplateSelector
        : DataTemplateSelector
    {
        public DataTemplate WidgetTemplate{get;set;}
        public DataTemplate ItemTemplate{get;set;}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        protected override DataTemplate SelectTemplateCore(object item)
        {
            if(item is ItemViewModel)
                return ItemTemplate;

            if(item is WidgetViewModel)
               return WidgetTemplate;

            return null;
        }

        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
             if(item is ItemViewModel)
                return ItemTemplate;

            if(item is WidgetViewModel)
               return WidgetTemplate;

            return null;
        } 
    }
}

TestItemsControl 是:

public class TestItemsControl : ItemsControl
{
   public TestItemsControl()
   {
        DefaultStyleKey = typeof(TestItemsControl);
   }

    protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return item is TestItem;
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new TestItem();
        }
}

TestItem 基本上是:

public class TestItem : ContentControl
{
   public TestItem()
   {
      DefaultStyleKey = typeof(TestItem);
   }

}

他们的风格:


<Style TargetType="local:TestItem">
 
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="VerticalAlignment" Value="Stretch" />
        <Setter Property="VerticalContentAlignment" Value="Stretch" />
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:TestItem">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <Grid>
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                              Content="{TemplateBinding Content}"
                                              ContentTemplate="{TemplateBinding ContentTemplate}"
                                              ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
                                              FontFamily="{TemplateBinding FontFamily}"
                                              FontSize="{TemplateBinding FontSize}"
                                              FontStyle="{TemplateBinding FontStyle}"
                                              FontWeight="{TemplateBinding FontWeight}"
                                              Foreground="{TemplateBinding Foreground}" />
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

<Style TargetType="local:TestItemsControl">
        <Setter Property="Padding" Value="0" />
        <Setter Property="Margin" Value="0" />
        <Setter Property="BorderBrush" Value="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
        <Setter Property="Background" Value="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="VerticalAlignment" Value="Stretch" />
        <Setter Property="VerticalContentAlignment" Value="Stretch" />
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <VariableSizedWrapGrid />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:TestItemsControl">
                    <Grid x:Name="PART_Root">
                        <Rectangle x:Name="PointerOverRect"
                                   Margin="-2"
                                   Fill="#DE000000"
                                   Opacity="0" />

                        <Border x:Name="PART_Border"
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">

                            <Grid Margin="{TemplateBinding Padding}">
                                <ItemsPresenter />
                            </Grid>
                        </Border>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="PointerOver">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="PointerOverRect"
                                                         Storyboard.TargetProperty="Opacity"
                                                         To="0.28"
                                                         Duration="0" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="PointerPressed" />
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="PART_Border"
                                                         Storyboard.TargetProperty="Opacity"
                                                         To="0.3"
                                                         Duration="0" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

最后是我如何创建项目:

public class TestPage : Page
{
    public TestPage()
    {
        InitializeComponent();
        var vm = new HomePageViewModel();
        DataContext = vm;

        var widget = new WidgetViewModel();
        widget.Add(new ItemViewModel
                   {
                        Name = "Users"
                   });
         widget.Add(new ItemViewModel
                   {
                        Name = "16"
                   });
         vm.Widgets.Add(widget);
    }
}

我有两个问题:(

第一个问题是:ItemTemplate 已设置,但它不显示项目的名称,但此文本:“Project.ItemViewModel”,我不明白为什么

第二个问题是子容器没有填满它的父容器。

为了解释我想要实现的目标,基本思想是让一个组件在延迟后交换其内容。

所以在这里我有一个带有项目的 GridView,每个项目都可以有很多内容。

这就是我使用TestItemsControl 的原因。用它管理交换内容更容易......

有任何想法吗?

编辑:我做了一些步骤。我还有一个问题。它是:DataTemplate 已设置到容器中,但未应用。当我在 DataTemplateSelector 上断点时,我看到我的 TestItemContainer 并在其中设置了 DataTemplateSelector,但是该项目始终显示一个带有文本“XXXX.XXXX.ViewModel”的文本块并且使用数据模板我需要显示属性“名称”视图模型

谢谢你的帮助

4

0 回答 0