WPF控件初始化的顺序-IsEnabled



我遇到了一个问题,当我启动程序时,在代码完全初始化并准备好处理它们之前,我会立即在滑块上获取ValueChanged事件。

滑块的XAML是

    <Slider Name="ZoomSlider" HorizontalAlignment="Left"    Margin="930,191,0,0"    VerticalAlignment="Top"
    Width="212" Height="30" TickPlacement="BottomRight" TickFrequency="2"  Maximum="200"
 Minimum="12"  IsEnabled="False" Value="50"  ValueChanged="ZoomSlider_ValueChanged"  />

请注意,IsEnabled设置为False。

但在事件处理程序中,如果我询问控件的状态,它将返回true。

private void ZoomSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    var slider = sender as Slider;
    bool b = ZoomSlider.IsEnabled;  // says TRUE!
    double value = slider.Value;   // retrieve value
    GlobalZoom = value / 50;
}  

在我的主窗口初始化代码中,只要调用InitializeComponent(),就会立即调用该事件,但当它从该调用返回时,IsEnabled返回false。事实上,如果我执行F11并尝试进入InitializeComponent()调用,它会立即转到ValueChanged事件处理程序。

 . . . 
    InitializeComponent();
    bool b = ZoomSlider.IsEnabled;  // says FALSE!
 . . . 

所以我很困惑。如果我在XAML中将其设置为false,为什么它总是true并触发事件?

编辑:在我的文章的原始版本中,在分配XAML中的处理程序后,我设置了IsEnabled="False",有些人认为这是由于XAML据称对评估顺序敏感,而不是XML,所以导致了问题的产生。所以我切换了上面的顺序,这对问题没有影响。

使用布尔标志来保持简单:

privat bool initializing = false;
public MainWindows()
{
    initializing = true;
    InitializeComponent();
    initializing = false;
}
private void ZoomSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    if ( initializing )
        return;
   //Normal flow
}

尝试在分配Maximum="200" 之前移动IsEnabled="False"。XAML中有一种赋值顺序,而不是XML。

是的,秩序可能很重要。请考虑XAML读取涉及到对象的创建和对这些对象的属性赋值。不可能同时指定特性值,很明显,在指定所有特性之前,将先指定一个特性,然后再指定另一个特性。

更新:

CCD_ 3是CCD_其被注册到CCD_ 5事件处理程序。

正如您所看到的,它附加了RangeBase.OnValueChanged事件处理程序,因此IsEnabled不会影响此事件处理程序调用。

我建议您在初始化后将事件处理程序赋值转移到类构造函数中。

设置MaximumMinimum属性是强制Value属性,因此会调用值更改事件处理程序。

最新更新