2014-02-20 6 views
0

Должен сказать, что мне очень не нравится LongListSelector в WP8 и, как версия инструментария, намного лучше.Как отменить выбор выбранной строки в LongListSelector в WP8

Сначала это не совместимо с MVVM, поэтому я нашел этот код так, чтобы он был таким.

public class LongListSelector : Microsoft.Phone.Controls.LongListSelector 
    { 
     public LongListSelector() 
     { 
      SelectionChanged += LongListSelector_SelectionChanged; 
     } 

     void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      SelectedItem = base.SelectedItem; 
     } 

     public static readonly DependencyProperty SelectedItemProperty = 
      DependencyProperty.Register(
       "SelectedItem", 
       typeof(object), 
       typeof(LongListSelector), 
       new PropertyMetadata(null, OnSelectedItemChanged) 
      ); 

     private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var selector = (LongListSelector)d; 
      selector.SelectedItem = e.NewValue; 
     } 

     public new object SelectedItem 
     { 
      get { return GetValue(SelectedItemProperty); } 
      set { SetValue(SelectedItemProperty, value); } 
     } 
    } 

я сделал модель представления с использованием MVVM света

public class MainViewModel : ViewModelBase 
    { 

     public MainViewModel() 
     { 
      MyList = new ObservableCollection<Test> 
      { 
       new Test 
       { 
        Name = "test 1" 
       }, 
       new Test 
       { 
        Name = "test 2" 
       } 
      }; 

      ButtonCmd = new RelayCommand(() => Hit()); 
     } 

     private void Hit() 
     { 
      SelectedItem = null; 
     } 

     public ObservableCollection<Test> MyList { get; set; } 

     /// <summary> 
     /// The <see cref="SelectedItem" /> property's name. 
     /// </summary> 
     public const string SelectedItemPropertyName = "SelectedItem"; 

     private Test selectedItem = null; 

     /// <summary> 
     /// Sets and gets the SelectedItem property. 
     /// Changes to that property's value raise the PropertyChanged event. 
     /// </summary> 
     public Test SelectedItem 
     { 
      get 
      { 
       return selectedItem; 
      } 

      set 
      { 
       if (value != null) 
       { 
        MessageBox.Show(value.Name); 
       } 


       if (selectedItem == value) 
       { 
        return; 
       } 

       RaisePropertyChanging(() => SelectedItem); 
       selectedItem = value; 
       RaisePropertyChanged(() => SelectedItem); 
      } 
     } 


     public RelayCommand ButtonCmd 
     { 
      get; 
      private set; 
     } 

я сделал модель

public class Test : ObservableObject 
    { 
     public string Name { get; set; } 
    } 

я сделал XAML

<phone:PhoneApplicationPage 
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
          xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
          xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:ignore="http://www.ignore.com" 
          xmlns:local="clr-namespace:MvvmLight2" x:Class="MvvmLight2.MainPage" 
          mc:Ignorable="d ignore" 
          FontFamily="{StaticResource PhoneFontFamilyNormal}" 
          FontSize="{StaticResource PhoneFontSizeNormal}" 
          Foreground="{StaticResource PhoneForegroundBrush}" 
          SupportedOrientations="Portrait" 
          Orientation="Portrait" 
          shell:SystemTray.IsVisible="True" 
          DataContext="{Binding Main, Source={StaticResource Locator}}"> 

    <!--LayoutRoot is the root grid where all page content is placed--> 
    <Grid x:Name="LayoutRoot" 
     Background="Transparent"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 
     <local:LongListSelector ItemsSource="{Binding MyList}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 
      <local:LongListSelector.Resources> 
       <DataTemplate x:Key="ItemTemplate"> 
        <Grid> 
         <TextBlock Text="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="48"/> 
        </Grid> 
       </DataTemplate> 
      </local:LongListSelector.Resources> 
      <local:LongListSelector.ItemTemplate> 
       <StaticResource ResourceKey="ItemTemplate"/> 
      </local:LongListSelector.ItemTemplate> 
     </local:LongListSelector> 
     <Button Content="Unselect" HorizontalAlignment="Left" Margin="142,81,0,0" Grid.Row="1" VerticalAlignment="Top" Command="{Binding ButtonCmd, Mode=OneWay}"/> 
    </Grid> 

</phone:PhoneApplicationPage> 

, когда я нажимаю по первому элементу в списке, появляется окно сообщения, если я его ударил снова, ничего не происходит. Затем я ударил свою кнопку, которая отменяет выбранный элемент (который в старой версии инструментария будет достаточным) и повторите попытку, и ничего не произойдет.

Единственный способ, которым я могу выбрать первую строку, - это выбрать вторую строку, которая действительно плоха, если в списке только 1 элемент в любой момент времени.

Странно, что простая коллекция строк даже не требует от меня, чтобы SelectItem был нулевым, поскольку он всегда кажется отмене, но когда дело доходит до сложных типов, это не выход.

+0

Было бы полезно увидеть код ButtonCmd. Единственный способ, по которому событие изменения не срабатывает, - это отсутствие воспринимаемого изменения. – lsuarez

+0

Весь код отправлен, ButotnCmd запускает метод Hit(), который просто устанавливает SelectedItem равным null; – chobo2

ответ

0

вы можете легко достичь с помощью в SelectionChanged случае

void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      if((sender as LongListSelector).SelectedItem == null){ 

      return; 
      } 

      SelectedItem = base.SelectedItem; 
      (sender as LongListSelector).SelectedItem = null; 
     } 
+0

Хмм, этот код нарушает приложение. Я думаю, что это происходит потому, что когда список загружается, ничего не выбрано, когда я пытаюсь выбрать что-то, нулевая проверка не позволит его установить. – chobo2

+0

@ chobo2, почему вы хотите сохранить выбранный вами элемент, вы получите это, когда вам понадобится – techloverr

+0

@ Romasz, который я поставил перед тем, как сделать его нулевым, как он предложил в вопросе – techloverr

1

Я использовал тот же код и побежал в ту же самую проблему. Причина в том, что свойство SelectedItem затмевает свойство base.SelectedItem. При установке его на новое значение, не только установить свойство SelectedItem но база одна, а:

public new object SelectedItem 
    { 
     get { return GetValue(SelectedItemProperty); } 
     set 
     { 
      SetValue(SelectedItemProperty, value); 
      base.SelectedItem = value; 
     } 
    } 

Тогда у вас есть MVVM способный код и может сбросить SelectedItem в вашей ViewModel, а также (установив его ноль).

Смежные вопросы