Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在DP更改值后启用并聚焦禁用的控件_C#_Wpf - Fatal编程技术网

C# 在DP更改值后启用并聚焦禁用的控件

C# 在DP更改值后启用并聚焦禁用的控件,c#,wpf,C#,Wpf,我有一个文本框,只有当计数器>=0时才必须启用它。另外,当计数器从-1变为0时,文本框必须获得键盘焦点 查看: <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="h

我有一个
文本框
,只有当
计数器>=0时才必须启用它。另外,当
计数器
从-1变为0时,
文本框
必须获得键盘焦点

查看:

<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>
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();
    }
}
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--;
    }
}
视图模型:

<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>
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();
    }
}
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--;
    }
}
当计数器变为正或负时,代码会启用和禁用控件,如果我注释
数据触发器
,则当计数器从0变为1时,控件会获得焦点

它们单独工作正常,但不能同时工作。我的猜测是,
DataTrigger
触发得太晚了,但不知道为什么

为什么
DataTrigger
执行得太晚了?还是
Focus()
太快了?


如何使它们都工作,如果可能,如何维护MVVM模型?

使用
IsEnabledChanged
事件处理程序解决此问题:

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

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

私有void ThingyBox\u已更改(对象发送方,DependencyPropertyChangedEventArgs e)
{
((文本框)sender.Focus();
}
如果有其他代理启用此ofc,它将不起作用,但对于当前场景,它将起作用=)