1

ID、Text、Colourなどのいくつかのパブリックプロパティと「SelectedItem」と呼ばれるブール値を保持する非常に単純なクラスがあります。RadioButtonsのプロパティと同様に、特定のグループ内でプロパティを設定Checkedできるのは1つのアイテムのみです。注:いくつかの個別のグループ(リスト)があり、それぞれが。を含むアイテムを1つだけ持つことができます。SelectedItemTrueSelectedItem = True

私の最初の考えは、おそらくクラス外のすべてを処理する必要があり、別のアイテムが選択されたときに特定のリスト内の他のすべてのアイテムに設定SelectedItemする必要があるということでした。Falseしかし、それは私にはかなりエレガントではないようです。だから私はこれがクラス内でどのように行われるのかを考えようとしてきました。例:「GroupName」というプライベート文字列プロパティ(Newクラスの新しいインスタンスを追加するときにサブに設定)を設定し、プライベート共有メソッドを使用してすべてのアイテムのSelectedItemプロパティをFalseに設定できますか?アイテムに同じものがある場合GroupName新しく選択したアイテムとして?私はこれをやろうと思っていますが、そのクラス内からクラスのすべてのインスタンスを列挙する方法、またはそれが可能かどうかさえわかりません。それは...ですか?または、私の目標を達成するための別の(より良い)方法はありますか?


編集

すべての提案とコメントをありがとう、それらはすべて非常に感謝しています。

TimとCyborgx37のコメントに基づいて、私は彼らのアドバイスに従い、CollectionBaseをアイテムマネージャークラスとして使用することにしました。これは私がこれまでに得たものの縮小版です:

Public Class ResourceItem
    Public ID As Integer
    Public Text As String
    Public SelectedItem As Boolean
End Class

Public Class ResourceItemsManager
    Inherits System.Collections.CollectionBase

    Public Sub Add(ByVal iID As Integer, ByVal sText As String)
        Dim newResItem As New ResourceItem
        With newResItem
            .ID = iID
            .Text = sText
        End With
        List.Add(newResItem)
    End Sub

    Default Public ReadOnly Property Item(ByVal Index As Integer) As ResourceItem
        Get
            If Index < Count And Index >= 0 Then
                Return CType(List.Item(Index), ResourceItem)
            Else
                Return Nothing
            End If
        End Get
    End Property

    Public Sub ClearAll()
        List.Clear()
    End Sub

    Public Sub SelectItem(ByVal Index As Integer)
        If Index < Count And Index >= 0 Then
            For i As Integer = 0 To List.Count - 1
                List.Item(i).SelectedItem = i = Index
            Next
        Else
            'Exception code here
        End If
    End Sub
End Class

ResourceItemご覧のとおり、新しいものをインスタンス化してそれをマネージャーのAddプロシージャへの引数として渡す代わりに、新しいアイテムの詳細を渡すだけで、プロシージャはそれらからアイテムを作成します。これが良いアイデアか悪いアイデアかはわかりませんが、アドバイスしてください。ただし、SelectedItemプロパティをマネージャーだけが書き込み可能にする方法がわからなかったため、直接アクセスできないようにしたかったのです。同じグループ内の他のすべてのアイテムの選択を解除せずにSelectedItemプロパティを設定できるオブジェクト。Trueもちろん、それでもマネージャーのリスト項目の1つに変数を設定し、そこから設定する可能性は残っているので、可能であれば、それを防ぐ方法を知りたいと思います。


更新
私は最終的に上記のコードを使用せず、代わりにCyborgx37のソリューションを使用することにしました。これは、ベストプラクティスに関する警告にもかかわらず、私にとっては完全にうまく機能しているようです。また、複数のアイテムを選択できる別のシナリオで同じクラスを使用する必要があることもわかったので、それを有効にするためにブール型プロパティをマネージャーに追加するのは簡単でした。

4

2 に答える 2

1

これは非常に単純なソリューションです。すべてのベストプラクティスに従うわけではありませんが(たとえば、ItemManagerでItemsコレクションを公開することはおそらく悪い考えです)、中央マネージャーの概念と、マネージャーとインターフェイスする個々のアイテムのプロパティを示しています。

Module Module1

Sub Main()

    Dim l_itemManager As New ItemsManager()

    Dim l_item1 As New Item(l_itemManager) With {.Description = "Item 1"}
    Dim l_item2 As New Item(l_itemManager) With {.Description = "Item 2"}
    Dim l_item3 As New Item(l_itemManager) With {.Description = "Item 3"}
    Dim l_item4 As New Item(l_itemManager) With {.Description = "Item 4"}

    l_itemManager.SelectedItem = l_item1

    Console.WriteLine("Item 1 = " & If(l_item1.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("Item 2 = " & If(l_item2.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("Item 3 = " & If(l_item3.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("Item 4 = " & If(l_item4.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("")

    l_itemManager.SelectedItem = l_item2

    Console.WriteLine("Item 1 = " & If(l_item1.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("Item 2 = " & If(l_item2.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("Item 3 = " & If(l_item3.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("Item 4 = " & If(l_item4.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("")

    l_item3.IsSelected = True

    Console.WriteLine("Item 1 = " & If(l_item1.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("Item 2 = " & If(l_item2.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("Item 3 = " & If(l_item3.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("Item 4 = " & If(l_item4.IsSelected, "Selected", "Unselected"))
    Console.WriteLine("")

    Console.WriteLine("Press any key...")
    Console.ReadKey(True)

End Sub

Class ItemsManager

    Public Event SelectedItemChanged As EventHandler

    Public Items As New List(Of Item)

    Private _item As Item
    Public Property SelectedItem() As Item
        Get
            Return _item
        End Get
        Set(ByVal value As Item)
            _item = value
            RaiseEvent SelectedItemChanged(sender:=Me, e:=EventArgs.Empty)
        End Set
    End Property

End Class

Class Item

    Public Event IsSelectedChanged As EventHandler

    Private WithEvents _manager As ItemsManager
    Public ReadOnly Property Manager() As ItemsManager
        Get
            Return _manager
        End Get
    End Property

    Private _description As String
    Public Property Description() As String
        Get
            Return _description
        End Get
        Set(ByVal value As String)
            _description = value
        End Set
    End Property

    Public Property IsSelected() As Boolean
        Get
            Return Me.Manager.SelectedItem Is Me
        End Get
        Set(ByVal value As Boolean)
            If value Then
                Me.Manager.SelectedItem = Me
            Else
                Me.Manager.SelectedItem = Nothing
            End If
        End Set
    End Property

    Public Sub New(ByVal manager As ItemsManager)
        _manager = manager
        Me.Manager.Items.Add(Me)
    End Sub

    Private Sub _manager_SelectedItemChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles _manager.SelectedItemChanged
        RaiseEvent IsSelectedChanged(sender:=Me, e:=EventArgs.Empty)
    End Sub

End Class

End Module

編集:

ベストプラクティスと完全に一致しているわけではありませんが、このコードは機能します。ベストプラクティスはコンテキストに大きく依存するため、アプリケーションの詳細を知らなければ、「正しい」アプローチが何であるかを言うのは困難です。とは言うものの、マネージャーと子クラス(子クラスが状態を取得するためにマネージャーを呼び出している)の一般的な概念は、ほぼすべての状況で機能するはずです。

私は@TimSchmelterに同意します、CollectionBaseはあなたに最大の力を与えるつもりです。しかし、あなたはあなたの目的のためにそれほど多くの力を必要としないかもしれません。そして、あなたはまだ私が投稿したものと同様のコードを使用しなければならないことになります-子供たちは親に彼らのステータスを尋ねます。

注:上記のコードの小さなバグを修正しました。選択したアイテムを選択されていないものに設定しても、何も起こりませんでした。この動作を変更して、SelectedItemをNothingにしました。

于 2012-06-01T17:31:19.937 に答える
1

コレクションをctorのクラスに渡し、そこでリストを繰り返すことができます。

   List<People> peoples = new List<people>();
   peoples.add(new People("Group1", peoples));
   peoples.add(new People("Group1", peoples));
   peoples.add(new People("Group1", peoples));


   Public Class People, iNotifyPropertyChanged
   {
      private List<People> peoples;
      private bool isChecked = false;

      public book IsChecked 
      { 
          get { return isChecked; }
          set 
          {
              if(isChecked = value) return;
              isChecked = value;
              if (isChecked)
              {
                  foreach (person p in peoples)
                  {
                      if (p.Ischecked && p != this)  p.Uncheck();
                  }
              }
          }
      }
      public void Uncheck
      {
          isChecked = false;
          NotifyPropertyChanged("IsChecked");
      }

      public People(string group, List<People> _peoples { peoples = _peoples; };
   }
于 2012-06-01T18:07:47.427 に答える