后退按钮专注于列表操作

时间:2013-04-30 10:45:46

标签: c# windows-8 windows-store-apps winrt-xaml

我正在创建一个ListView,可以从中删除一些项目(这是收藏夹列表),选择它们,打开应用栏并点击“从收藏夹中删除”。单击该按钮时,系统会要求当前视图模型中的方法从列表中删除此项。发生这种情况后,UI会更新,并删除该项目。

现在,我有两个问题。第一个是当一个项目被移除时,页面的后退按钮会获得焦点(它会得到一个虚线轮廓),这是我不想要的。

第二个问题是列表不使用添加/删除动画我已将其设置为使用。

任何一种解决方案都将受到赞赏。

以下是一些显示会发生什么的伪代码:

XAML:

<GridView x:Name="FavoritesGridView"
    Grid.Row="1"
    SelectionMode="Multiple"
    ItemTemplate="{StaticResource FavoritesOnSectionViewItemTemplate}"
    ItemsSource="{Binding FavoritesList}" 
    ItemClick="ProgramGrid_OnItemClick" 
    IsItemClickEnabled="True"
    SelectionChanged="FavoritesGridView_OnSelectionChanged"
    ScrollViewer.HorizontalScrollMode="Disabled">
    <GridView.ItemContainerStyle>
      <Style TargetType="Control">
        <Setter Property="Margin" Value="0,0,38,8"/>
      </Style>
    </GridView.ItemContainerStyle>
    <GridView.ItemContainerTransitions>
      <TransitionCollection>
        <AddDeleteThemeTransition/>
      </TransitionCollection>
    </GridView.ItemContainerTransitions>
    <GridView.ItemsPanel>
      <ItemsPanelTemplate>
        <WrapGrid Orientation="Vertical" MaximumRowsOrColumns="9" />
      </ItemsPanelTemplate>
    </GridView.ItemsPanel>
</GridView>

代码隐藏:

private void UnFavoriteButton_Click(object sender, RoutedEventArgs e)
{          
    viewModel.RemoveFromFavorites(FavoritesGridView.SelectedItems.Cast<FavoriteProgram>().AsEnumerable());
}

视图模型:

public void RemoveFromFavorites(IEnumerable<FavoriteProgram> programs)
{
    FavoriteController.RemoveFromFavorites(programs);
    UpdateUi();
}

private void UpdateUi()
{
    OnPropertyChanged("FavoritesList");
}

public IEnumerable<FavoriteProgram> FavoritesList
{
    get { return CoreData.TvFavorites; } // A centralized list
}

FavoritesController:

public static void RemoveFromFavorites(IEnumerable<FavoriteProgram> programs)
{
    if (programs.IsNullOrEmpty()) return;
    foreach (var program in programs)
        RemoveFromFavorites(program);
}

public static void RemoveFromFavorites(FavoriteProgram program)
{
    if (!IsFavorite(program)) return;

    var list = CoreData.TvFavorites.ToList();
    list.Remove(program);
    CoreData.TvFavorites = list.AsEnumerable();
}

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

我明白了。所以你有两个问题。

[1]。后退按钮获得焦点。

我认为Back按钮永远不会得到焦点。已经有一个关键的姿态要回去,所以设置焦点是愚蠢的。我不知道为什么它没有被禁用有焦点。这就是你所做的一切:

<Button TabIndex="-1" Style="{StaticResource BackButtonStyle}" />

或者你可以用一种风格来做:

<Grid Background="Black">
    <Grid.Resources>
        <Style TargetType="Button" BasedOn="{StaticResource BackButtonStyle}" x:Name="MyBackButtonStyle">
            <Setter Property="TabIndex" Value="-1" />
        </Style>
    </Grid.Resources>
    <Button Style="{StaticResource MyBackButtonStyle}" />
</Grid>

使用这种新样式(或只是更新现有样式)将导致后退按钮永远不会获得焦点。如果您希望它能够获得焦点,出于某种原因,那么解决方案就是处理GotFocus事件并简单地使用(sender as Button).Focus(FocusState.Unfocused);。公平地说,你还应该确定为什么要取消焦点。

[2]。动画没有发生

这是一个常见问题。原因是,您不想在ListView上设置动画,而是想在ListView ItemsPanel上设置动画。这就是你想做的一切:

<ListView>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel>
                <StackPanel.ChildrenTransitions>
                    <AddDeleteThemeTransition />
                </StackPanel.ChildrenTransitions>
            </StackPanel>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

就这么简单。 (我的示例是StackPanel,请记住在代码中使用WrapGrid。您只是在错误的位置进行了转换。所以,现在你可以处理你所拥有的焦点问题,并且可以获得你想要的转换。

我可能会提供一些建议。由于您使用的是视图模型,听到您还没有使用委托命令听起来很奇怪。如果您想最好地使用MVVM,委托命令可以为您解决许多问题。请在此处阅读:http://blog.jerrynixon.com/2012/08/most-people-are-doing-mvvm-all-wrong.html

并提出第二点建议。听起来我可能正在使用Visual Studio中的默认模板。大多数开发人员都从那问题是这些模板对于教授最佳实践并不是很好。我的建议:不要害怕空白模板。

祝你好运!

答案 1 :(得分:2)

  

现在,我有两个问题。第一个是后面的按钮   当一个项目时,页面会收到焦点(它会得到一个虚线轮廓)   删除,我不想要的东西。

通过向GridView的SelectedItem属性添加TwoWay-Binding,可以解决此问题。删除喜欢的程序后,为每个代码设置SelectedItem,以便它集中在GridView中。

<强> XAML:

<GridView x:Name="FavoritesGridView"
          SelectedItem="{Biding SelectedFavorite, Mode=TwoWay}" />

<强> C#:

private FavoriteProgram _selectedFavorite;

public FavoriteProgram SelectedFavorite {
  get {
    return _selectedFavorite;
  }
  set {
    _selectedFavorite = value;
    OnPropertyChanged("SelectedFavorite");
  }
}

删除商品后,将属性SelectedFavorite设置为FavoritesList中的商品。

public void RemoveFromFavorites(IEnumerable<FavoriteProgram> programs) {
  FavoriteController.RemoveFromFavorites(programs);

  UpdateUi();

  SelectedItem = FavoritesList.FirstOrDefault(); // selects the first element in list.
}
  

第二个问题是列表不使用添加/删除   动画我已将其设置为使用。

此处的问题是,在删除收藏夹后,您始终会为属性CoreData.TvFavorites使用新的收藏/列表,因此GridView无法确定哪些项目已被删除或添加。

对于绑定方案,有一个名为ObservableCollection<T>的专用集合,它实现了接口INotifyCollectionChanged。该接口定义了一个事件,用于通知(UI元素)项目在集合中添加或删除。您应该将属性FavoritesList更改为键入ObservableCollection<FavoriteProgramm>并更新UpdateUI方法中的集合以删除相关的收藏夹。

private void UpdateUi()
{ 
   //Update your FavoritesList to enable animations.
    OnPropertyChanged("FavoritesList");
}

private ObservableCollection<FavoriteProgram> _favorites;
public ObservableCollection<FavoriteProgram> FavoritesList
{
  get { 
    if (_favorites == null) {
      _favorites = new ObservableCollection<FavoriteProgram>();
    }

    return _favorites; 
  }
}