经过大量研究,我确实需要你的帮助。在研究时,我发现了几篇这样的文章:
如何将模型更改从模型传达给 ViewModel
双向绑定到模型中的数组
INotifyPropertyChanged 不更新数组属性.
但是,我没有正确应用一些东西。
设置:
INotifyChanged
在Model和ViewModel中实现一个属性是一个存储某种活动的枚举。根据它的值,视图将更新背景颜色。 这工作正常.
另一个属性是存储一组候选人的整数列表。在运行时,候选集将减少,直到只剩下一个数字。我想在视图中显示这些更改。 这根本行不通.
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 事件(如果我对此进行了适当的研究)。建议是用 ObservableCollection 替换 ArrayList,我这样做了,但它仍然没有像我期望的那样工作。
private ArrayList _IntersectingSet; //first attempt
/// <summary>
/// A set of digits that is the intersection of the tree 'SetOfCandidates' properties.
/// <br></br>A digit must be out of a set, where D = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.
/// <para>
/// <br></br>If there is just one member in this <see cref="ArrayList"/>, then it is the <see cref="Value"/>.
/// </para>
/// </summary>
public ArrayList IntersectingSet { get => _IntersectingSet; set => _IntersectingSet = value; }
private ObservableCollection<int> _SetOfCandidates; //second attempt
/// <summary>
/// My test to fire EventChanged in View
/// </summary>
public ObservableCollection<int> SetOfCandidates { get => _SetOfCandidates; set => SetProperty(ref _SetOfCandidates, value); }
public class SudokuCandidateToContentConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string contentValue = string.Empty;
//var arrayList = (ArrayList)value; //first attempt
var arrayList = (ObservableCollection<int>)value; //second attempt
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>
这里有一些图片。
亲爱的社区,如果您对我有任何建议,请帮助我。感谢您的意见。如果你看到一个更聪明的方法来实现我的想法,请告诉我。