У меня есть следующий сценарий: представление с tabControl и кнопкой:
<Window x:Class="some"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Settings" Height="412" Width="586"
DataContext="{Binding SettingsViewModel}">
<Grid>
...
<TabControl Name="TabControlSettings" Grid.Row="0" Grid.ColumnSpan="3" Margin="10, 10, 10, 10">
<TabItem Header="settings1">
...
</TabItem>
<TabItem Header="settings1">
...
</TabItem>
<TabItem Header="settings2">
...
</TabItem>
<TabItem Header="settings3">
...
</TabItem>
<TabItem Header="settings3">
...
</TabItem>
</TabControl>
<Button Grid.Row="1" Grid.Column="2" Name="btn_Ok" Content="Ok" HorizontalAlignment="Left" Width="50" Height="23" Margin="10" Command="{Binding SaveSettingsCommand}" Click="btn_Ok_Click" />
</Grid>
некоторые проверки пользовательского интерфейса отслеживаются в событии btn_Ok_Click, определенном в коде:
private void btn_Ok_Click(object sender, RoutedEventArgs e)
{
bool HasErrors = false;
HasErrors = !ViewServices.IsValid(TabControlSettings);
if (HasErrors)
{
var control = ViewServices.controlToValidate.Values.First() as System.Windows.Controls.Control;
control.Focus();
}
else
{
this.Close();
}
}
ViewServices - это просто вспомогательный класс, который предоставляет некоторые методы для Views, как в случае IsValid:
public static Dictionary<bool, object> controlToValidate;
/// <summary>
/// validates all binding rules on a dependency object and its children:
/// </summary>
/// <param name="obj">Dependency object</param>
/// <returns>True if none of the child objects has errors, False otherwise</returns>
internal static bool IsValid(DependencyObject parent)
{
controlToValidate = new Dictionary<bool, object>();
// The dependency object is valid if it has no errors,
//and all of its children (that are dependency objects) are error-free.
if (Validation.GetHasError(parent))
{
var obj = GetTabItem(parent);
controlToValidate.Add(false, obj);
return false;
}
foreach (DependencyObject child in LogicalTreeHelper.GetChildren(parent).OfType<DependencyObject>())
{
if (!IsValid(child))
{
if (controlToValidate.Count == 0)
{
var obj = GetTabItem(child);
controlToValidate.Add(false, obj);
}
return false;
}
}
return true;
}
internal static object GetTabItem(DependencyObject obj)
{
var parent = LogicalTreeHelper.GetParent(obj);
var parentControl = parent as System.Windows.Controls.Control;
if (parentControl != null)
{
if (parentControl.GetType() != typeof(System.Windows.Controls.TabItem))
{
return GetTabItem(parent);
}
else
return parentControl;
}
else
{
return GetTabItem(parent);
}
}
С помощью этого метода я получаю tabitem, содержащий элементы управления с ошибками проверки.
Теперь снова возвращаемся к событию btn_OK_Click в коде:
HasErrors = !ViewServices.IsValid(TabControlSettings);
if (HasErrors)
{
var control = ViewServices.controlToValidate.Values.First() as System.Windows.Controls.Control;
control.Focus();
}
else
{
this.Close();
}
Я заметил, что событие Click кнопки вызывается до команды, связанной с кнопкой (я прав?).
Я хочу избежать выполнения команды SaveSettingsCommand, если значение HasErrors равно true.как это можно сделать?