2015-08-30 1 views
0

У меня есть TextBox, который должен быть включен только в том случае, если Counter >= 0. Также, когда Counter идет от -1 до 0, TextBox должен получить фокус клавиатуры.Включить и сфокусировать отключенное управление после изменения значения DP

Вид:

<Window x:Class="Thingy.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:Thingy" 
     mc:Ignorable="d" 
     Title="Not random title" Height="200" Width="250"> 
    <Grid VerticalAlignment="Center" HorizontalAlignment="Center"> 
     <Grid.Resources> 
      <local:IsNegativeConverter x:Key="IsNegativeConv"/> 
      <Style x:Key="BoxStyle" TargetType="TextBox"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding Counter, Converter={StaticResource IsNegativeConv}}" Value="True"> 
         <!-- Here is the problem =(--> 
         <Setter Property="IsEnabled" Value="False"/> 
        </DataTrigger> 
       </Style.Triggers> 
       <Setter Property="Width" Value="90"/> 
      </Style> 
     </Grid.Resources> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 

     <Grid Grid.Row="0"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="*"/> 
      </Grid.ColumnDefinitions> 
      <Label Grid.Column="0" Margin="2">Thingy</Label> 
      <TextBox x:Name="ThingyBox" Grid.Column="1" Style="{StaticResource BoxStyle}"/> 
     </Grid> 
     <Grid Grid.Row="1"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*"/> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="*"/> 
      </Grid.ColumnDefinitions> 
      <Button Grid.Column="0" Content="-" Command="{Binding Decrease}" /> 
      <Label Grid.Column="1" Content="{Binding Counter}" Margin="2"/> 
      <Button Grid.Column="2" Content="+" Command="{Binding Increase}" /> 
     </Grid> 
    </Grid> 
</Window> 

Code-за:

public partial class MainWindow : Window 
{ 
    public ViewModel ViewModel { get; private set; } 
    public MainWindow() 
    { 
     ViewModel = new ViewModel(); 
     DataContext = ViewModel; 
     ViewModel.OnCounterChanged += OnCounterChanged; 
     InitializeComponent(); 
    } 

    private void OnCounterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     if ((int)e.OldValue == -1 && (int)e.NewValue == 0) 
      ThingyBox.Focus(); 
    } 
} 

ViewModel:

public class ViewModel : DependencyObject 
{ 
    public event PropertyChangedCallback OnCounterChanged; 

    public int Counter 
    { 
     get { return (int)GetValue(CounterProperty); } 
     set { SetValue(CounterProperty, value); } 
    } 
    public static readonly DependencyProperty CounterProperty = 
     DependencyProperty.Register("Counter", typeof(int), typeof(ViewModel), new PropertyMetadata(-2, CounterChanged)); 
    private static void CounterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     ViewModel vm = (ViewModel)d; 
     if (vm.OnCounterChanged != null) 
      vm.OnCounterChanged(d, e); 
    } 

    RelayCommand c_Increase; 
    public ICommand Increase 
    { 
     get 
     { 
      if (c_Increase == null) 
       c_Increase = new RelayCommand(p => this.IncreaseExecute(p), null); 

      return c_Increase; 
     } 
    } 
    private void IncreaseExecute(object parameter) 
    { 
     Counter++; 
    } 

    RelayCommand c_Decrease; 
    public ICommand Decrease 
    { 
     get 
     { 
      if (c_Decrease == null) 
       c_Decrease = new RelayCommand(p => this.DecreaseExecute(p), null); 

      return c_Decrease; 
     } 
    } 
    private void DecreaseExecute(object parameter) 
    { 
     Counter--; 
    } 
} 

делает код активации процедуры d отключите управление, когда счетчик будет положительным или отрицательным, и, если я прокомментирую DataTrigger, управление получает фокус, когда счетчик переходит от 0 до 1.

Индивидуально они работают правильно, но они не работают на в то же время. Я предполагаю, что DataTrigger запускает слишком поздно, но не знаю почему.

Почему DataTrigger Выполняется слишком поздно? Или Focus() слишком скоро?

Как я могу заставить их работать и, если возможно, поддерживать модель MVVM?

ответ

0

Использование обработчика событий IsEnabledChanged решает эту проблему:

<TextBox x:Name="ThingyBox" IsEnabledChanged="ThingyBox_IsEnabledChanged"/> 

private void ThingyBox_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e) 
{ 
    ((TextBox)sender).Focus(); 
} 

Это не будет работать, если есть и другие средства, которые позволяют это OFC, но текущий сценарий работает =)

Смежные вопросы