2013-10-16 39 views
0

我正在使用MVVM模式構建應用程序。點擊其中一個元素後,我想查看此元素的詳細信息。我寫了這個:如何使用MVVM模式在LongListSelector中選擇一個項目?

XAML

<phone:LongListSelector ItemsSource="{Binding Data}" 
         Margin="0,0,0,158" 
         SelectedItem="{Binding SelectedItem}"> 
    <phone:LongListSelector.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <Button> 
       <!-- Command="{Binding ShowDetailsAction}"--> 
        <Button.Template> 
         <ControlTemplate> 
          <TextBlock Text="{Binding Text}"></TextBlock> 
         </ControlTemplate> 
        </Button.Template> 
       </Button> 
      </StackPanel> 
     </DataTemplate> 
    </phone:LongListSelector.ItemTemplate> 
</phone:LongListSelector> 

視圖模型:

public IEnumerable SelectedItem 
{ 
    get { return _itemsControl; } 
    set 
    { 
     if (_itemsControl == value) 
      return; 
     _itemsControl = value; 

     // Test 
     _mss.ErrorNotification("fd"); 
    } 
} 

我也嘗試使用命令,沒有工作了。

這是命令部分:

public ICommand ShowDetailsCommand { get; private set; } 

public ViewModel() 
{ 
    _loadDataCommand = new DelegateCommand(LoadDataAction); 
    SaveChangesCommand = new DelegateCommand(SaveChangesAction); 
    ShowDetailsCommand = new DelegateCommand(ShowDetailsAction); 
} 

private void ShowDetailsAction(object p) 
{ 
    _mss.ErrorNotification("bla bla"); 
} 

EDIT

視圖模型

private IEnumerable _itemsControl; 
public IEnumerable Data 
{ 
    get 
    { 
    return _itemsControl; 
    } 
    set 
    { 
    _itemsControl = value; 
    RaisePropertyChanged("Data"); 
    } 
} 

protected void RaisePropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler = PropertyChanged; 
    if (handler != null) 
    { 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

模型

public string Text { get; set; } 
public DateTimeOffset Data { get; set; } 

EDIT2

private MobileServiceCollection<ModelAzure, ModelAzure> _items; 
     private readonly IMobileServiceTable<ModelAzure> _todoTable = App.MobileService.GetTable<ModelAzure>(); 


private async void RefreshTodoItems() 
{ 
    try 
    { 
     _items = await _todoTable.ToCollectionAsync(); 
    } 
    catch (MobileServiceInvalidOperationException e) 
    { 
      _mss.ErrorNotification(e.ToString()); 
    } 
    Data = _items; 
} 
+0

您是否嘗試明確定義您在TwoWay模式下的SelectedItem綁定? (嘗試SelectedItem =「{綁定SelectedItem,模式= TwoWay}」) – AirL

+0

我添加Mode = TwoWay,但不工作。 – Serafins

+0

您能否提供更多的viewmodel代碼?查看Data屬性及其內容類型可能很有用。 – AirL

回答

0

Data財產看起來像

private MobileServiceCollection<ModelAzure, ModelAzure> _itemsControl; 
public MobileServiceCollection<ModelAzure, ModelAzure> Data 
{ 
    get 
    { 
    return _itemsControl; 
    } 
    set 
    { 
    _itemsControl = value; 
    RaisePropertyChanged("Data"); 
    } 
} 

編輯

看來SelectedItem property from LongListSelector cannot be bound in WP8。 你可以做的有兩種情況:

  • 使用中提供的鏈接上面,而不是默認的一個,它看起來像派生的和固定的定製LongListSelector:

    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); } 
        } 
    } 
    
  • 寄存器從SelectionChanged事件LongListSelector並在關聯的處理程序/回調中自行調用您的ViewModel:

在您的視圖中:

<phone:LongListSelector x:Name="YourLongListSelectorName" 
         ItemsSource="{Binding Data}" 
         Margin="0,0,0,158" 
         SelectionChanged="OnSelectedItemChanged"> 
在後面的代碼

private void OnSelectedItemChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs e) 
{ 
    ((YourViewModel)this.DataContext).NewSelectedItemMethodOrWhateverYouWant((ModelAzure)this.YourLongListSelectorName.SelectedItem); 
    //or 
    ((YourViewModel)this.DataContext).SelectedItem = (ModelAzure)this.YourLongListSelectorName.SelectedItem; 
} 

最後你Button命令不能正常工作,因爲當你使用DataTemplate,該ambiant DataContext的是項目本身。這意味着它在尋找你的Command到您的Model實例,而不是到你的ViewModel實例。

希望這會有所幫助

+0

我不知道..但_itemsControl不能在此同時IEnumerable和模型的類型。 – Serafins

+0

我已經編輯我的回答;) – AirL

+0

的SelectionChanged = 「OnSelectedItemChanged」< - 錯誤的方法簽名。 在後面的代碼只接受簽名:(對象發件人,SelectionChangedEventArgs selectionChangedEventArgs) – Serafins

0

在您的視圖模型,您有:

public IEnumerable SelectedItem 
{ 
get { return _itemsControl; } 
set 
{ 
    if (_itemsControl == value) 
     return; 
    _itemsControl = value; 

    // Test 
    _mss.ErrorNotification("fd"); 
} 

}

爲什麼你的SelectItem一個IEnumerable?它應該不是「型號」類型嗎?您的列表綁定到「數據」應該是ObservableList,而不是IEnumerable。它將提供它自己的更改通知,所以你不需要。

列表將在SelectedItem被選中時設置它,但如果類型錯誤,它將不會被設置。

格雷格

+0

因爲我正在從Azure讀取數據。加載數據的IEnumerable比可觀察到的更容易...我添加更多的代碼到我的文章 – Serafins

相關問題