UWP Gridview绑定到View Model

时间:2017-07-04 00:28:26

标签: c# xaml gridview

我在UserControl中使用GridView来显示一个五乘四方形的图形按钮,可以选择一个课程。

这是我升级到Windows 10 UWP的Windows 8.1商店应用程序。

我之前使用Tap和Right-Tap操作来选择课程或激活CommandBar以通过SelectionChanged事件为课程执行相关操作。但是,Interactions现在在Windows 10下的工作方式发生了变化,我无法让Gridview完全工作,将SelectedItem绑定到视图模型中的选定LessonButton,也不能将SelectionChanged和ItemClick事件用于此类目的。 Gridview选择行为不起作用,因为一旦选择了一个项目,它就永远不会被取消选择。最后,我采取了不同的策略,并尝试了Gridview项目的Tap和Right-Tap事件。但问题是,无论我采用哪种方式,我都无法使Binding正常工作。

所以我有一个名为LessonButton的对象:

public class LessonButton : INotifyPropertyChanged
{
    //public LessonButton() { }
    public LessonButton(SolidColorBrush inBackground, bool inComplete, double inHeight, int inNumber, bool inSelected, bool inStarted,
        Status inState, double inWidth)
    {
        ...
        Started = inStarted;
        ...
    }
    ...
    private bool _started;
    public bool Started
    {
        get { return _started; }
        set { if (_started != value) { _started = value; OnPropertyChanged(); } }
    }
    ...
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

它被添加到View Model中的可观察集合中:

public class LessonsViewModel : INotifyPropertyChanged
{
    public ObservableCollection<LessonButton> Lessons { get; } = new ObservableCollection<LessonButton>();

    private LessonButton _selectedLessonButton;

    public LessonButton SelectedLessonButton
    {
        get { return _selectedLessonButton; }
        set { if (_selectedLessonButton != value) { _selectedLessonButton = value; OnPropertyChanged(); } }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
} 

在用户控件中,我将DataContext设置为:

<UserControl.DataContext>
    <classes:LessonsViewModel/>
</UserControl.DataContext>

..然后我将GridView定义为:

        <GridView x:Name="LessonGridView" ItemContainerStyle="{StaticResource GridViewItemStyle}" ItemsSource="{Binding Lessons}"
              SelectionMode="Single" IsItemClickEnabled="False" SelectedItem="{Binding Path=SelectedLessonButton, Mode=TwoWay}">
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <VariableSizedWrapGrid HorizontalChildrenAlignment="Left" MaximumRowsOrColumns="5" Orientation="Horizontal" VerticalChildrenAlignment="Top"/>
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>
    </GridView>

将GridView项目格式在ControlTemplate中定义为GridViewItemStyle的一部分。

我尝试使用Binding和xBind以各种方式访问​​LessonButton变量,但只能使用此XAML使用ControlTemplate运行程序:

    <Image Grid.Row="1" Grid.Column="1" Width="{StaticResource BadgeSize}" 
    Height="{StaticResource BadgeSize}" HorizontalAlignment="Right" VerticalAlignment="Top"
    Opacity="{Binding Started, Converter={StaticResource OpacityConverterTrueValueIsVisible}}"
    Source="/Assets/SelectionButtonGroup/square310x310logobw.png" Stretch="Uniform"/>

转换器只返回1或0,具体取决于bool Started的值。

虽然此代码有效,但它不正确并且Visual Studio报告未知错误并声明它找不到Started属性。事实上它无法找到LessonButton的任何属性,而且我也无法找到正确的公开语法,即使使用x:绑定代码如下:

{x:Bind LessonViewModel.Lessons.LessonButton.Selected}

..或其版本,使用铸造等。

我正在使用Visual Studio 2017 Enterprise,它报告上述错误并在整个ControlTemplate上显示波浪线,并显示错误,其中找不到与此代码甚至无关的另一个转换器工件。这本身就让我感到非常恼火。是我还是VS中的XAML Intellisence看起来非常不稳定,因为如果它无法确定真实错误的根本原因,它会放弃并报告错误的错误?

理想情况下,我希望Gridview SelectedItem与ViewModel绑定。但即使通过Tap事件尝试操作,我也无法通过绑定来正确地公开ControlTemplate XAML中的LessonButton属性。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

您不应该使用ItemContainerStyle绑定LessonButton个变量。 ItemContainerStyle用于为项目设置选择标记,悬停和按下状态等样式。

您应该使用存储在DataTemplate资源中的UserControl,如下所示:

<Grid>
  <Grid.Resources>
    <DataTemplate x:Name="GridViewTemplate">
      <TextBlock Text="{Binding LessonName}">
    </DataTemplate>
  </StackPanel.Resources>
  <GridView x:Name="GridView"
            ItemsSource="{Binding Lessons}"
            ItemTemplate="{StaticResource GridViewTemplate}">
  </GridView>
</Grid>

然后为您的DataTemplate提供一个名称(上面的#34; GridViewTemplate&#34;)并将其设置为ItemTemplate的{​​{1}}。