c# - 为什么 ObservableCollection 中的验证红色框出现在容器的左上角?
问题描述
我在文本框中遇到验证问题,我将尝试以简单的方式重现。我正在使用本身包含 ObservableColletion 的对象的 ObservableColletion。在我的 UserControls 中,我绑定到我正在使用验证的对象的属性(在此示例中为 IDataErrorInfo)。问题是当我用已经插入的数据启动程序时。如果数据几乎没有错误,红色验证框会出现在正确的位置(错误所在的文本框),但如果我有超过一定数量的错误,红色框开始出现在列表容器的左上角. 有人可以向我解释发生了什么,我该如何解决这个问题?
这是代码:
<Window ...>
<Window.Resources>
<DataTemplate DataType="{x:Type local:Group}">
<local:UserControlGroup/>
</DataTemplate>
</Window.Resources>
<GroupBox Header="Group List">
<ListBox BorderThickness="0" ItemsSource="{Binding Groups}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</GroupBox>
</window>
在部分类中,我创建了 7 个类似的对象:
public partial class MainWindow : Window
{
public ObservableCollection<Group> Groups { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
Groups = new ObservableCollection<Group>()
{
new Group()
{
Name = "Group01",
Type = "AAAA",
ItemList = new ObservableCollection<Item>()
{
new Item()
{
Value1 = -2,
Value2 = -1
},
new Item()
{
Value1 = -2,
Value2 = -1
},
new Item()
{
Value1 = -2,
Value2 = -1
},
new Item()
{
Value1 = -2,
Value2 = -1
},
new Item()
{
Value1 = -2,
Value2 = -1
},
new Item()
{
Value1 = -2,
Value2 = -1
}
}
},
new Group()
{
Name = "Group02",
Type = "BBBB",
ItemList = new ObservableCollection<Item>()
{
new Item()
{
Value1 = -2,
...
...
new Group()
{
Name = "Group07",
Type = "BBBB",
ItemList = new ObservableCollection<Item>()
{
...
类和用户控件:
public class Group : IDataErrorInfo
{
public string Name { get; set; }
public string Type { get; set; }
public ObservableCollection<Item> ItemList { get; set; }
public string Error => throw new NotImplementedException();
public string this[string columnName]
{
get
{
if (columnName == nameof(Name))
{
if (string.IsNullOrEmpty(Name)) return "Value can't be empty.";
}
return string.Empty;
}
}
}
<UserControl ...>
<UserControl.Resources>
<DataTemplate DataType="{x:Type local:Item}">
<local:UserControlItem/>
</DataTemplate>
</UserControl.Resources>
<GroupBox Header="{Binding Name}">
<StackPanel>
<TextBox HorizontalAlignment="Left" Width="70" Margin="4" Text="{Binding Type, ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}"/>
<ItemsControl ItemsSource="{Binding ItemList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</GroupBox>
</UserControl>
public class Item : IDataErrorInfo
{
public int Value1 { get; set; }
public int Value2 { get; set; }
public string Error => throw new NotImplementedException();
public string this[string columnName]
{
get
{
if (columnName == nameof(Value1))
{
if (Value1 < 0) return "Value can't be negative.";
}
else if (columnName == nameof(Value2))
{
if (Value1 < 0) return "Value can't be negative.";
}
return string.Empty;
}
}
}
<UserControl ...>
<StackPanel Orientation="Horizontal">
<TextBox Width="70" Margin="4" Text="{Binding Value1, ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Width="70" Margin="4" Text="{Binding Value2, ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</UserControl>
解决方案
我仍然不知道是什么导致了这个问题,但至少我找到了一个在 TextBox 中使用 AdornerDecorator 并定义它们的边距的解决方案:
<UserControl ...>
<StackPanel Orientation="Horizontal">
<AdornerDecorator Margin="4">
<TextBox Width="70" Margin="1" Text="{Binding Value1, ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}"/>
</AdornerDecorator>
<AdornerDecorator Margin="4">
<TextBox Width="70" Margin="1" Text="{Binding Value2, ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}"/>
</AdornerDecorator>
</StackPanel>
</UserControl>
推荐阅读
- arm - 如何指示 ARM cortext 进行中断的尾链或堆栈弹出抢占?
- javascript - 在 Angular 页面中显示本地存储的值
- authentication - 在 ASP.NET Core 中为 Web Api 使用 JWT 而不是 Cookie 身份验证的原因
- c++ - 来自 CRTP 基础的 Operator++ 对编译器不可见
- arrays - 如何正确读取未格式化的数组
- reactjs - 路由组件未在状态更改时更新,console.log 显示与组件的行为方式相反
- flutter - 无法使用 ListView ( Flutter ) 在 Stack 内滚动 MapView
- angular - 按列值对 mat-table 进行排序
- java - JAVA - 如何绕过没有打开标记的封闭 XML 标记
- sql-server-2005 - 日期的递归 CTE