经过大量研究,我确实需要你的帮助。我的第一个版本的评论一直在帮助我寻找新的关键词。
在研究时我发现了几篇这样的文章:
CollectionChanged的信息
实现 CollectionChanged
但是,我理解和应用不正确。
问题:
Activity
和 SetOfCandidates
来理解这一点吗?BindingList
、ObservableCollection
、性能、CollectionChanged
调用PropertyChanged
的赞成和反对。在这里设置我的项目时我需要记住什么?CollectionChanged
被提出后,我该怎么办?我无法让 UI 做我想做的事。设置:
INotifyChanged
在Model和ViewModel中实现BindingList
也被测试了;对于这个线程,我坚持ObservableCollection
CollectionChanged
为物业实施SetOfCandidates
一个属性是一个存储某种活动的枚举。根据它的值,视图将更新背景颜色。 这工作正常.
另一个属性是存储一组候选人的整数列表。在运行时,候选集将减少,直到只剩下一个数字。我想在视图中显示这些更改。 这根本行不通.
Activity 属性运行良好。在初始化时,颜色没有设置,在运行时,颜色会根据 Activity 中存储的内容而改变。
/// <summary>
/// This <see cref="Enum"/> is used to define the activities,
/// how the algorithm is finding a candidate.
/// </summary>
public enum Activity
{
Clue,
Singleton,
Single,
Twin,
Triple,
BruteForce,
Initialization,
}
private Activity _Activity;
/// <summary>
/// This property stores the activity performed to manipulate the cell.
/// This can be used in the View to make this activity visible
/// by using a converter changing the background color.
/// </summary>
public Activity Activity { get => _Activity; set => SetProperty(ref _Activity, value); }
public class SudokuValueColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (Enum.IsDefined(value.GetType(), value) == false)
return DependencyProperty.UnsetValue;
var activity = (Activity)value;
switch (activity)
{
case Activity.Clue:
return Brushes.Blue;
case Activity.Singleton:
return Brushes.Orange;
case Activity.Single:
return Brushes.Green;
case Activity.Twin:
return Brushes.Brown;
case Activity.Triple:
return Brushes.Yellow;
case Activity.BruteForce:
return Brushes.Red;
case Activity.Initialization:
return null;
default:
return Brushes.Black;
}
}
}
因此,我试图将其应用于物业
SetOfCandidates
。在第一次运行中,这个属性是一个ArrayList
。这是行不通的,因为更改数组的成员不会引发PropertyChanged
事件(如果我对此进行了适当的研究-经过更多研究,我会说没有像ArrayList
,BindingList
或ObservableCollection
这样的类型
正在引发此事件,如果仅更改内容)。建议是用 ArrayList
替换 ObservableCollection
,我这样做了,但它仍然没有像我期望的那样工作。在对线程发表第一条评论后,我正在查找CollectionChanged
。调试了一下发现确实没有输入SetOfCandidates
的setter,在编辑内容的时候。作为下一步,我将 CollectionChanged
事件添加到设置器中。在这个事件处理程序中,我放置了一个Debug.Writeline()
,现在我看到了这个事件被引发的频率。
private ObservableCollection<int> _SetOfCandidates;
public ObservableCollection<int> SetOfCandidates
{
get => _SetOfCandidates;
set
{
Debug.WriteLine($"Passing Setter of {nameof(SetOfCandidates)}");
SetProperty(ref _SetOfCandidates, value);
SetOfCandidates.CollectionChanged += SetOfCandidates_CollectionChanged;
}
}
private void SetOfCandidates_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
Debug.WriteLine($"Passing {nameof(SetOfCandidates_CollectionChanged)}");
OnPropertyChanged(nameof(_SetOfCandidates));
}
public class SudokuCandidateToContentConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string contentValue = string.Empty;
var arrayList = (ObservableCollection<int>)value;
if (arrayList == null) return "+"; //just for testing
if (arrayList.Count == 0) return "++"; //just for testing
//if (arrayList == null) return contentValue;
//if (arrayList.Count == 0) return contentValue;
foreach (var item in arrayList)
{
if (item == (int)parameter)
{
contentValue = (string)parameter;
}
}
return contentValue;
}
}
我的期望:
我希望在应用程序启动时在视图中显示一个空字符串。稍后,用户正在加载一个数独游戏,将线索放入视图中。在这种情况下,这些特定单元格的 SetOfCandidates 计数为零,标签内容为空字符串。所有其他未设置任何值的单元格都根据算法的逻辑更新它们的 SetOfCandidates。标签的内容应该使 SetOfCandidates 在视图中可见。
发生了什么事? 只有在启动应用程序时,才会调用更新标签内容的转换器。这与每当绑定属性发生变化时调用的 SudokuValueColorConverter 形成对比。
这是xaml代码。 Border 中的转换器工作正常。 Label 中的转换器只被调用一次。
<Border Style="{StaticResource borderSudokuCandidatesCell}" Background="{Binding Sudoku[0].Activity, Converter={StaticResource sudokuValueColorConverter}}">
<UniformGrid>
<Label
Content="{Binding Sudoku[0].SetOfCandidates, Converter={StaticResource sudokuCandidateToContentConverter}, ConverterParameter=1}"
Style="{StaticResource labelSudokuCandidates}">
</Label>
<Label
<!-- *** repeated with changing ConverterParameter from 1 to 9 ***-->
<Label
Content="{Binding Sudoku[0].SetOfCandidates, Converter={StaticResource sudokuCandidateToContentConverter}, ConverterParameter=9}"
Style="{StaticResource labelSudokuCandidates}">
</Label>
</UniformGrid>
</Border>
这里有一些图片。
亲爱的社区,如果您对我有任何建议,请帮助我。感谢您的意见。如果你看到一个更聪明的方法来实现我的想法,请告诉我。