wpf如何判断在其它操作时,重绘使用禁止

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wpf如何判断在其它操作时,重绘使用禁止相关的知识,希望对你有一定的参考价值。

参考技术A WPF与WinForm开发的区别:

WPF开发于WinForm之后,从技术发展的角度,WPF比WinForm先进是不容置疑的。WPF相比于WinForm有下面的一些较好的特性:
1、解决Window Handle问题
在Windows GDI或WinForm开发中复杂的GUI应用程序,会使用的大量的控件,如Grid等。而每个控件或Grid cell都是一个小窗口,会使用一个Window handle,尽管控件厂商提供了很多优化办法,但还是会碰到Out of Memory或"Error Create Window handle",而导致程序退出。
WPF彻底改变了控件显示的模式,控件不在使用窗口,也就不会占用Window handle。理论上,如果一个WPF只有一个主窗口的话,WPF只会使用一个Window handle(如果忽略用于Dispatcher的隐藏窗口的话)。所以WPF GUI程序不会出现Window handle不够用的情况。
2、多线程的处理
在WinForm程序开发时,最头疼的一个问题就是,worker线程修改控件的属性而导致程序崩溃,而且这种非法操作并不是每次都失败。WinForm控件提供了InvokeRequired属性来判断当前线程是不是控件创建线程。问题是当控件树很深是,这个属性会比较慢。
WPF开始设计的时候,就考虑到了多线程的问题。大部分的WPF类都继承于DispatcherObject。DispatcherObject实际就是对Dispatcher的一个简单封装。Dispatcher提供了类似InvokeRequired的方法(CheckAccess)。这个方法只是比较线程的ID,所以会很快。另外,Dispatcher提供了优先队列,异步调用,Timer等功能,简化了开发多线程GUI程序。

禁止/阻止选择 wpf 中禁用的组合框项目

【中文标题】禁止/阻止选择 wpf 中禁用的组合框项目【英文标题】:Disallow/Block selection of disabled combobox item in wpf 【发布时间】:2014-01-20 07:33:39 【问题描述】:

我正在编写一个应用程序,其中我想禁用 ComboBox 中的几个项目,并且还想禁止/阻止选择禁用的项目。请注意,主窗口中的 ComboBox 有另一个 ComboBox 作为 ComboBox Item init(由数据模板选择器在运行时决定)。

使用下面的代码,我可以禁用 ComboBox 中的 ComboBox,但它不会阻止用户选择该禁用的 ComboBox 项。禁止/阻止选择禁用项目的任何帮助都会有所帮助。

下面是代码sn-ps

主窗口中的组合框:

<Grid>
    <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" 
              Width="120" Margin="87.2,44.8,0,0" 
              ItemsSource="Binding Cars" 
              ItemsPanel="DynamicResource ItemsPanelTemplateHorizontal"
              ItemTemplateSelector="StaticResource QualityComboBoxTemplateSelector"
              SelectedItem="Binding SelectedItm"/>
</Grid>

数据模板选择器:

public class QualityComboBoxTemplateSelector : DataTemplateSelector

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    
        var element = container as FrameworkElement;

        var dataTemplate = element.FindResource(((item is string) && item.Equals("Ferrari")) ?
                                                       "DataTemplateTopLevelCombobox2" : "DataTemplateTopLevelCombobox1") as DataTemplate;

        return dataTemplate;
    

以上 ComboBox 的数据模板:

<DataTemplate x:Key="DataTemplateTopLevelCombobox1">
    <Border BorderBrush="Black" BorderThickness="1" >
        <TextBlock HorizontalAlignment="Left" 
                   TextWrapping="Wrap" Text="Binding"     
                   VerticalAlignment="Top"/>
    </Border>
</DataTemplate>

<DataTemplate x:Key="DataTemplateTopLevelCombobox2">
    <Border Width="100">
        <ComboBox Text="Custom" Height="21.96"
        ItemsSource="Binding DataContext.Models, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type Window"
        IsEnabled="Binding DataContext.EnableCombo, RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type Window" />
    </Border>
</DataTemplate>

【问题讨论】:

【参考方案1】:

您可以通过将ComboBoxItemIsEnabled 属性设置为false 来实现此目的;

因此,ComboBox 的ItemSource 中的每个项目(即在您的情况下为Cars)都可以是具有某些属性(例如IsSelectable)的对象,该属性指定是否应启用或禁用它,然后将其与样式一起使用不可选择的项目。像这样 -

<Style TargetType="ComboBoxItem"> 
   <Setter Property="IsEnabled" Value="Binding IsSelectable"/> 
</Style> 

更新:

<Grid>
    <ComboBox
        Width="120"
        Margin="87.2,44.8,0,0"
        HorizontalAlignment="Left"
        VerticalAlignment="Top"
        ItemTemplateSelector="StaticResource QualityComboBoxTemplateSelector"
        ItemsPanel="DynamicResource ItemsPanelTemplateHorizontal"
        ItemsSource="Binding Cars"
        SelectedItem="Binding SelectedItm">
        <ComboBox.ItemContainerStyle>
            <Style TargetType="ComboBoxItem">
                <Setter
                    Property="IsEnabled"
                    Value="Binding IsSelectable" />
            </Style>
        </ComboBox.ItemContainerStyle>
    </ComboBox>
</Grid>

【讨论】:

其实我没有用ComboboxItemStyle,我用的是DataTemplate。 @vmore 我已经更新了我的答案,展示了如何应用 ComboBoxItem 样式。 @vmore 很高兴它有帮助:) 这不是防止选择的一致方式。您仍然可以通过将焦点放在控件中并键入来搜索它来选择禁用的项目。它会毫无问题地选择它。 我希望我这样做了,现在我正在通过允许选择但阻止任何进一步的操作(即选择被认为对表单无效)来解决它。您必须挂钩查找行为以过滤掉所有禁用的项目。不过,这似乎是控件的一个明显错误,所以我不确定为什么它仍然会以这种方式运行。【参考方案2】:

解决@JordyBoom 指出的问题。

ItemsContainerGenerator 在下拉菜单至少打开一次之前不会生成项目。

因此,如果您在窗口的加载事件处理程序中打开下拉菜单并再次将其关闭,那么所有的鼠标和键盘选择都应该可以正常工作。

    public MainWindow()
    
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(onLoaded);
    

    private void onLoaded(object sender, RoutedEventArgs e)
    
         cmbx.IsDropDownOpen = true;
         cmbx.IsDropDownOpen = false;
    

来源:WPF: Making combo box items disabled – also when accessed using the keyboard

【讨论】:

谢谢。上下箭头键可用于在组合被删除之前浏览项目,并且允许在没有此修复的情况下进行选择。禁用的项目是某些人的分隔符。

以上是关于wpf如何判断在其它操作时,重绘使用禁止的主要内容,如果未能解决你的问题,请参考以下文章

android涂鸦工具,笔刷的定义,撤销与重绘

实现没有饥饿的while循环以在wpf中重绘图像

VC 鼠标滚轮事件控制绘图的问题

目标 C. ScrollView:每次用户滚动时如何强制它重绘可见部分?

回流与重绘

单击时重绘可可应用程序的主窗口