我有一个非常简单的类,它包含一些公共属性--ID,Text,Color等,以及一个名为'SelectedItem'的布尔值。就像RadioButtons上的Checked
属性一样,只有一个项目可以将SelectedItem
属性设置为特定组中的True
。注意:将有几个单独的组(列表),每个组只允许一个项目SelectedItem = True
。
我的第一个想法是,我可能只需要处理课外的所有内容,当选择另一个项目时,为特定列表中的每个其他项目设置SelectedItem
到False
。但这对我来说似乎相当不优雅。所以我一直在想着如何在这个类中完成它。例如:我可能有一个名为“GroupName”的私有字符串属性 - 在添加类的新实例时在New
子集中设置 - 然后使用私有共享方法设置每个项目的{{1}属性为SelectedItem
,提供该项目与新选择的项目具有相同的False
?我会这样做,但我不知道如何枚举该类中的每个实例,或者是否可能。是吗?或者是否有另一种(更好的)方法来实现我的目标?
修改
感谢所有的建议和意见,我们非常感谢。
在Tim和Cyborgx37的评论背后,我决定遵循他们的建议并使用CollectionBase作为项目经理类。这是我到目前为止的简化版本:
GroupName
可以看出:我没有实例化一个新的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
过程,而是简单地传递新项目的详细信息并且过程正在创建这些项目。我不知道这是好还是坏 - 请告知 - 但我已经完成了,因为我无法弄清楚如何使SelectedItem属性只能由经理写,所以我想避免直接访问可以将Add
属性设置为SelectedItem
的对象,而不取消选择同一组中的所有其他项目。当然,这仍然有可能将变量设置为管理者列表项之一并从那里设置,所以我仍然想知道如果可能的话我怎么能阻止它。
更新
我最后没有使用上面的代码,而是选择使用Cyborgx37的解决方案 - 尽管有关于最佳实践的警告,这似乎对我来说非常好。我还意识到我需要在另一个可以选择多个 项的情况下使用相同的类,因此很容易向管理器添加一个布尔属性来启用它。
答案 0 :(得分: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无效。
答案 1 :(得分: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; };
}