내 .NET 4.0 WPF 응용 프로그램에는 ListBox
. 는 ListBox
처음에 비어 있습니다. 대화 상자에는 사용자가 항목을 ListBox
. MVVM을 사용하고 있으며 뷰 모델 클래스는 IDataErrorInfo
. 가 ObservableCollection
받는 바인드 뷰 모델 클래스의 ListBox's ItemsSource
속성입니다.
사용자가 .NET Framework에 하나 이상의 항목을 입력 할 때까지 확인을 클릭하도록하고 싶지 않습니다 ListBox
. ListBox
이 비어 있으면 ListBox's
도구 설명에 오류 메시지와 함께 빨간색 테두리와 오른쪽에 오류 아이콘을 표시하고 싶습니다 . 이것이 내 응용 프로그램에 다른 모든 오류가 표시되는 방식입니다.
다음은 XAML의 편집 된 버전입니다.
<Window x:Class="MyDialog class's type"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cs="clr-namespace:MyControlsDLL's namespace"
xmlns:vm="clr-namespace:My View Model DLL's namespace"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
DataContext="{Binding Path=SelectedCamera, RelativeSource={RelativeSource Self}}"
Loaded="MyDialog_Loaded"
SizeToContent="Height"
cs:ThemeSelector.CurrentThemeDictionary="{Binding Path=TimeOfDayTheme, RelativeSource={RelativeSource Self}}"
Width="800"
WindowStartupLocation="CenterOwner">
<cs:MyDialog.CommandBindings>
<cs:DataContextCommandBinding CanExecute="CanAddOrEditItem" Command="cs:MyCommands.AddItem" Executed="AddOrEditItem" />
<cs:DataContextCommandBinding CanExecute="CanRemoveItem" Command="cs:MyCommands.RemoveItem" Executed="RemoveItem" />
</cs:MyDialog.CommandBindings>
<cs:MyDialog.Resources>
<ResourceDictionary>
<BitmapImage x:Key="ErrorImage" UriSource="Resources/Error.png" />
<cs:BooleanInverter x:Key="NOT" />
<cs:BooleanToVisibilityConverter x:Key="BoolToVisibile" True="Visible" False="Collapsed" />
<cs:BooleanToVisibilityConverter x:Key="BoolToCollapsed" True="Collapsed" False="Visible" />
<cs:EnumToBooleanConverter x:Key="SubTypeConverter" />
<cs:MultiBoolConverter x:Key="BoolCombiner" />
<cs:EnumDisplayer ResourceManager="{x:Static res:MyApp.ResourceManager}" Type="{x:Type sys:DateTimeKind}" x:Key="DateTimeKinds">
<cs:EnumOverride EnumValue="Local" ResourceKey="DateKind_Local" />
<cs:EnumOverride EnumValue="Unspecified" ResourceKey="DateKind_Unspecified" />
<cs:EnumOverride EnumValue="Utc" ResourceKey="DateKind_Utc" />
</cs:EnumDisplayer>
<cs:EnumDisplayer ResourceManager="{x:Static res:MyApp.ResourceManager}" Type="{x:Type vm:MyTypes}" x:Key="MyTypes" />
<ControlTemplate x:Key="InputErrorTemplate">
<DockPanel LastChildFill="True">
<Image DockPanel.Dock="Right"
Height="20"
Margin="-30,0,0,0"
Source="{StaticResource ErrorImage}"
ToolTip="{x:Static res:MyApp.Common_InvalidData}"
VerticalAlignment="Center"
Width="20" />
<Border BorderBrush="Red"
BorderThickness="5"
Margin="5,5,30,5">
<AdornedElementPlaceholder />
</Border>
</DockPanel>
</ControlTemplate>
<Style TargetType="{x:Type ListBox}">
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource InputErrorTemplate}" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip">
<Setter.Value>
<Binding Path="(Validation.Errors).CurrentItem.ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource InputErrorTemplate}" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip">
<Setter.Value>
<Binding Path="(Validation.Errors).CurrentItem.ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</cs:MyDialog.Resources>
<Grid Name="LayoutRoot" Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<AdornerDecorator Grid.Row="0">
<Grid Name="CommonRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Column2" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0"
Grid.Row="0"
Margin="5"
Text="Name:"
TextAlignment="Right"
VerticalAlignment="Center" />
<TextBox Grid.Column="1"
Grid.Row="0"
Margin="5,5,30,5"
MaxLength="50"
Name="NameBox"
TabIndex="0"
Text="{Binding Mode=TwoWay, NotifyOnSourceUpdated=True, Path=Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
TextAlignment="Left"
VerticalAlignment="Center" />
<TextBlock Grid.Column="3"
Grid.Row="0"
Margin="5"
Text="Type:"
TextAlignment="Right"
VerticalAlignment="Center" />
<ComboBox Grid.Column="4"
Grid.Row="0"
Height="50"
ItemsSource="{Binding Source={StaticResource MyTypes}, Path=DisplayNames}"
SelectedValue="{Binding Converter={StaticResource MyTypes}, Mode=TwoWay, Path=MyType}"
SelectionChanged="LPRTypePicker_SelectionChanged"
Margin="5"
x:Name="MyTypePicker"
TabIndex="1"
VerticalAlignment="Center" />
<TabControl Grid.Column="0"
Grid.ColumnSpan="6"
Grid.Row="1"
Name="Tabs">
<TabItem Header="Tab 1"
Name="Tab1">
<AdornerDecorator>
<Border BorderBrush="{DynamicResource ELDControlBorder}"
BorderThickness="0,0,0,1">
<Grid Background="{DynamicResource ELDContentBackground}"
Name="LPRConfiguration">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Column2" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!-- Row definitions -->
</Grid.RowDefinitions>
<!-- Controls for this TabItem -->
</Grid>
</Border>
</AdornerDecorator>
</TabItem>
<TabItem Header="Directories List"
Visibility="{Binding Path=CanShow, Converter={StaticResource BoolToVisibile}}">
<AdornerDecorator>
<Border BorderThickness="0,0,0,1">
<Grid Name="Tab2Root">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" SharedSizeGroup="Column1" />
<ColumnDefinition Width="3.5*" />
<ColumnDefinition Width="110" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Right"
Margin="5"
Text="Mode:" />
<Grid Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<RadioButton Content="SubType 1"
Grid.Column="1"
GroupName="SubTypes"
IsChecked="{Binding Converter={StaticResource SubTypeConverter}, ConverterParameter=SubType1, Path=SubType}"
Margin="5"
TabIndex="8"
VerticalAlignment="Center" />
<RadioButton Checked="SubType_Changed"
Content="Value2"
Grid.Column="3"
GroupName="SubTypes"
IsChecked="{Binding Converter={StaticResource SubTypeConverter}, ConverterParameter=SubType2, Path=SubType}"
Margin="5"
Name="SubTypeSubType2Button"
TabIndex="8"
VerticalAlignment="Center" />
</Grid>
<TextBlock Grid.Column="0"
Grid.Row="2"
HorizontalAlignment="Right"
Margin="5"
Text="An Item:"
VerticalAlignment="Center"
Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}" />
<Grid Grid.Column="1"
Grid.Row="2"
Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Margin="5"
Name="NewItemBox"
TabIndex="11"
Text="{Binding Mode=TwoWay, Path=NewItem, UpdateSourceTrigger=PropertyChanged}"
ToolTip="{x:Static res:MyApp.MyDialog_NewItem_Tooltip}"
VerticalAlignment="Center" />
<Button Command="cs:MyCommands.Browse"
Content="Browse..."
Grid.Column="1"
Height="35"
Margin="5"
Name="BrowseDirectoriesButton"
TabIndex="12" />
</Grid>
<Button Command="cs:MyCommands.AddItem"
Content="{Binding Path=AddOrEditLabel}"
Grid.Column="2"
Grid.Row="2"
Height="50"
Margin="5"
Name="AddItemButton"
TabIndex="13" />
<TextBlock Grid.Column="0"
Grid.Row="3"
HorizontalAlignment="Right"
Margin="5"
Text="Selected Items:"
TextAlignment="Right"
TextWrapping="WrapWithOverflow"
Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}" />
<ListBox Grid.Column="1"
Grid.Row="3"
Height="160"
ItemsSource="{Binding Path=SelectedItems}"
Margin="5,5,30,5"
Name="ItemsList"
SelectedValue="{Binding Mode=TwoWay, Path=SelectedItem, ValidatesOnDataErrors=True}"
TabIndex="14"
Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}" />
<Button Command="cs:MyCommands.RemoveItem"
Content="Remove"
Grid.Column="2"
Grid.Row="3"
Height="50"
Margin="5"
Name="RemoveItemButton"
TabIndex="15"
VerticalAlignment="Top"
Visibility="{Binding Converter={StaticResource BoolToVisibile}, Path=SubTypeIsSubType1}" />
</Grid>
</Border>
</AdornerDecorator>
</TabItem>
</TabControl>
</Grid>
</AdornerDecorator>
<!-- OK & Cancel Buttons here -->
</Grid>
</Window>
여기 ListBox
에는 이것이 처음에는 비어 있지만 Type 속성이 하나의 값이고 SubType 속성이 SubType1 인 경우 비어있는 것은 오류 일 뿐이라는 점에서 복잡합니다. 처음에는 이러한 속성에 해당 값이 없습니다. 대화 상자가 처음 표시되면 유효성 검사 코드가 호출되는 것을 볼 수 있지만 표시 ListBox
되지 않기 때문에 오류가 표시 되지 않습니다.
Type 속성을 변경하면 SubType 속성이 자동으로 SubType1로 설정되고 ListBox
가 표시되고 비어 있습니다. View Model 클래스 IDataErrorInfo
구현 의 유효성 검사 코드 가 호출되고 오류 메시지가 반환되지만 오류 템플릿이 표시되지 않는지 확인할 수있었습니다. 사실 그 탭에는 오류가 전혀 표시되지 않고, 오류를 표시하는 이전 탭과 동일하다고 생각합니다.
내가 뭘 잘못 ListBox
했니?
편집하다
A는이 TextBox
있음에 Tab
그 또한 오류 상태 초기에 및 오류 메시지가 표시되지되고 있었다. 텍스트를 넣으면 유효성 검사 코드가 실행되고 OK로 표시되었습니다. 그러나 비 웠을 때 오류 상태가 표시되었습니다. 내 문제는 사용자가 Type1을 선택하거나 SubType을 변경할 때 오류 상태로 전환하기 위해 무언가를해야한다는 것입니다.
나는 그것을 작동시켰다. ValidatesOnDataErrors=True
의 ItemsSource
속성에 대한 바인딩을 추가 ListBox
했으며 이제 오류 템플릿이 표시됩니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다