2012-01-27 6 views
2

Caliburn micro(1.3)/ MVVMとSilverlightを使用しています。 itemsource RadGridViewを更新すると、選択したアイテムが失われます。 MVVMを実装するときに、選択した項目を保存する動作を実装する方法についてのブログを見つけました。選択したアイテムを取得することはできますが、アイテムソースを一度リフレッシュすると戻すことはできません。 someoneshow私はどのようにcaliburn.microとRadGridVIewを使用して実装することができますか?私は、キャリバンマイクロコンベンションを作成するのが最善の方法だと思っていますが、selectedItemではなくselectedItemのコンベンションを作成するためのリファレンスしか見つけることができません。caliburn.micro/Telerik RadGridView/Silverlightの使用時に選択した項目を保存します

これを達成する方法を教えてもらえますか?私は以下を試しましたが、うまくいきません。

private static void SetRadGridSelecteditemsConventions() 
    { 
     ConventionManager 
      .AddElementConvention<DataControl>(DataControl.ItemsSourceProperty, "SelectedItem", "SelectionChanged") 
      .ApplyBinding = (viewModelType, path, property, element, convention) => 
           { 
            ConventionManager.SetBinding(viewModelType, path, property, element, convention, DataControl.ItemsSourceProperty); 

            if (ConventionManager.HasBinding(element, DataControl.SelectedItemProperty)) 
             return true; 

            var index = path.LastIndexOf('.'); 
            index = index == -1 ? 0 : index + 1; 
            var baseName = path.Substring(index); 
            foreach (var selectionPath in 
             from potentialName in ConventionManager.DerivePotentialSelectionNames(baseName) 
             where viewModelType.GetProperty(potentialName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) != null 
             select path.Replace(baseName, potentialName)) 
            { 
             var binding = new Binding(selectionPath) { Mode = BindingMode.TwoWay }; 
             BindingOperations.SetBinding(element, DataControl.SelectedItemProperty, binding); 
            } 
            return true; 
           }; 
    } 

おかげで、 ステファン

答えて

1

selectedItemsのプロパティが読み取り専用であるため、あなたは、このための動作を使用する必要があります。 Telerikにはexampleがあります。例はcaliburn.microに固有のものではありません。 は、あなたのプロジェクトに以下のクラスを追加する場合:

public class MultiSelectBehavior : Behavior<RadGridView> 
{ 
    public INotifyCollectionChanged SelectedItems 
    { 
     get { return (INotifyCollectionChanged)GetValue(SelectedItemsProperty); } 
     set { SetValue(SelectedItemsProperty, value); } 
    } 

    public static readonly DependencyProperty SelectedItemsProperty = 
     DependencyProperty.Register("SelectedItems", typeof(INotifyCollectionChanged), typeof(MultiSelectBehavior), new PropertyMetadata(OnSelectedItemsPropertyChanged)); 


    private static void OnSelectedItemsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args) 
    { 
     var collection = args.NewValue as INotifyCollectionChanged; 
     if (collection != null) 
     { 
      collection.CollectionChanged += ((MultiSelectBehavior)target).ContextSelectedItems_CollectionChanged; 
     } 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     AssociatedObject.SelectedItems.CollectionChanged += GridSelectedItems_CollectionChanged; 
    } 

    void ContextSelectedItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     UnsubscribeFromEvents(); 

     Transfer(SelectedItems as IList, AssociatedObject.SelectedItems); 

     SubscribeToEvents(); 
    } 

    void GridSelectedItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     UnsubscribeFromEvents(); 

     Transfer(AssociatedObject.SelectedItems, SelectedItems as IList); 

     SubscribeToEvents(); 
    } 

    private void SubscribeToEvents() 
    { 
     AssociatedObject.SelectedItems.CollectionChanged += GridSelectedItems_CollectionChanged; 

     if (SelectedItems != null) 
     { 
      SelectedItems.CollectionChanged += ContextSelectedItems_CollectionChanged; 
     } 
    } 

    private void UnsubscribeFromEvents() 
    { 
     AssociatedObject.SelectedItems.CollectionChanged -= GridSelectedItems_CollectionChanged; 

     if (SelectedItems != null) 
     { 
      SelectedItems.CollectionChanged -= ContextSelectedItems_CollectionChanged; 
     } 
    } 

    public static void Transfer(IList source, IList target) 
    { 
     if (source == null || target == null) 
      return; 

     target.Clear(); 

     foreach (var o in source) 
     { 
      target.Add(o); 
     } 
    } 
} 

この動作は、収集RadGridView.SelectedItemsとMultiSelectBehavior.SelectedItems間の同期の世話をします。

は、今、私たちはのObservableCollectionを持っている必要がViewModelに

//Collection holding the selected items 
    private ObservableCollection<object> selectedGridItems; 
    public ObservableCollection<object> SelectedGridItems 
    { 
     get 
     { 
      if (selectedGridItems == null) 
       selectedGridItems = new ObservableCollection<object>(); 

      return selectedGridItems; 
     } 
     set 
     { 
      if (selectedGridItems == value) return; 
      selectedGridItems = value; 
      NotifyOfPropertyChange(() => SelectedGridItems); 
     } 
    } 

    //Deselect all selected items in the gridview 
    public void ClearSelectedGridItems() 
    { 
     SelectedGridItems.Clear(); 
    } 

に最後のものは、ビューこれだけ

<telerik:RadGridView x:Name="CustomLogs" AutoGenerateColumns="true" SelectionMode="Extended"> 
     <i:Interaction.Behaviors> 
      <local:MultiSelectBehavior SelectedItems="{Binding SelectedGridItems}"/>     
     </i:Interaction.Behaviors>     
    </telerik:RadGridView> 

に行動をバインドし、それはあなたの役に立てば幸いです!

関連する問題