【问题标题】:Changing elements of a toolbar from collapsed to visible doesn't change their visibility将工具栏的元素从折叠状态更改为可见状态不会改变它们的可见性
【发布时间】:2011-06-15 13:00:57
【问题描述】:

我整个晚上都在试图理解和解决我目前在使用工具栏时遇到的问题:

我创建了一个基于矢量的小型绘图程序,用户可以在其中选择工具(选择、线条、文本、图像等...),方法是在使用之前单击工具栏中的相应图标。

When a certain tool is selected, new controls appear in the toolbar (they have their visibility, which is originally set to collapsed, changed to visible), allowing the user to change its parameters.

例如,当单击文本工具时,会出现一个字段,用户可以在其中编写内容。选择图像工具时,会出现一个按钮,可打开一个OpenFileDialog(以选择源文件)等...

问题在于,在非常特殊的情况下,一些在选择相应工具时应该出现的元素仍然隐藏,即使它们的可见性在代码中设置为 true。而且缺少的控件也不在工具栏的溢出部分。

这很难解释,所以这里是一个源代码示例,它模仿我的应用程序并显示问题:创建一个新的 C# wpf 项目,然后将以下代码复制到 MainWindow.xaml 中

<Window x:Class="DDI.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="DDI" Height="250" Width="318">
<DockPanel Width="Auto" Height="Auto" LastChildFill="True">
    <StackPanel DockPanel.Dock="Top" ToolBarTray.IsLocked="True">
        <Menu>
            <MenuItem Header="Fichier">
                <MenuItem Header="Nouveau" />
                <MenuItem Header="Ouvrir" />
                <Separator />
                <MenuItem Header="Quitter" />
            </MenuItem>
        </Menu>
        <ToolBar Name="toolbar">
            <ToggleButton Name="tool_selection" Height="16" Width="16" Click="tool_selection_Click" Background="Yellow">
            </ToggleButton>
            <ToggleButton Name="tool_text" Height="16" Width="16" Click="tool_text_Click" Background="Red">
            </ToggleButton>
            <ToggleButton Name="tool_image" Height="16" Width="16" Click="tool_image_Click" Background="Blue">
            </ToggleButton>
            <Separator Name="tool_separator1" Margin="4,2" />
            <TextBlock Name="tool_name_caption" VerticalAlignment="Center" Margin="0,0,4,0" Visibility="Collapsed">
                Name :
            </TextBlock>
            <TextBox Name="tool_name_field" Width="80" BorderBrush="#FF6F6F6F" Visibility="Collapsed">
            </TextBox>
            <TextBlock Name="tool_content_caption" VerticalAlignment="Center" Margin="4,0,4,0" Visibility="Collapsed">
                Content :
            </TextBlock>
            <TextBox Name="tool_content_field" Width="100" BorderBrush="#FF6F6F6F" Visibility="Collapsed">
                Your text
            </TextBox>
            <TextBlock Name="tool_source_caption" VerticalAlignment="Center" Margin="4,0,4,0" Visibility="Collapsed">
                Source :
            </TextBlock>
            <TextBox Name="tool_source_field" Width="80" BorderBrush="#FF6F6F6F" IsReadOnly="True" AllowDrop="False" Visibility="Collapsed">
            </TextBox>
            <Button Name="tool_source_select" BorderBrush="#FF6F6F6F" Visibility="Collapsed">
                ...
            </Button>
            <TextBlock Name="tool_z_caption" VerticalAlignment="Center" Margin="4,0,4,0" Visibility="Collapsed">
                Z :
            </TextBlock>
            <TextBox Name="tool_z_field" Width="30" BorderBrush="#FF6F6F6F" Visibility="Collapsed">
                0
            </TextBox>
        </ToolBar>
    </StackPanel>
    <ScrollViewer HorizontalScrollBarVisibility="Visible">
        <Canvas Name="workspace" Background="White">

        </Canvas>
    </ScrollViewer>
</DockPanel>

以及对应的 *.cs 文件中的以下几行:

using System.Windows;

namespace DDI
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            SelectSelectionTool();
        }

        private void tool_selection_Click(object sender, RoutedEventArgs e)
        {
            SelectSelectionTool();
        }

        private void tool_text_Click(object sender, RoutedEventArgs e)
        {
            SelectTextTool();
        }

        private void tool_image_Click(object sender, RoutedEventArgs e)
        {
            SelectImageTool();
        }

        private void SelectSelectionTool()
        {
            tool_selection.IsChecked = true;
            tool_text.IsChecked = false;
            tool_image.IsChecked = false;

            tool_separator1.Visibility = Visibility.Collapsed;

            tool_name_caption.Visibility = Visibility.Collapsed;
            tool_name_field.Visibility = Visibility.Collapsed;

            tool_content_caption.Visibility = Visibility.Collapsed;
            tool_content_field.Visibility = Visibility.Collapsed;

            tool_source_caption.Visibility = Visibility.Collapsed;
            tool_source_field.Visibility = Visibility.Collapsed;
            tool_source_select.Visibility = Visibility.Collapsed;

            tool_z_caption.Visibility = Visibility.Collapsed;
            tool_z_field.Visibility = Visibility.Collapsed;
        }

        private void SelectTextTool()
        {
            tool_selection.IsChecked = false;
            tool_text.IsChecked = true;
            tool_image.IsChecked = false;

            tool_separator1.Visibility = Visibility.Visible;

            tool_name_caption.Visibility = Visibility.Visible;
            tool_name_field.Visibility = Visibility.Visible;

            tool_content_caption.Visibility = Visibility.Visible;
            tool_content_field.Visibility = Visibility.Visible;

            tool_source_caption.Visibility = Visibility.Collapsed;
            tool_source_field.Visibility = Visibility.Collapsed;
            tool_source_select.Visibility = Visibility.Collapsed;

            tool_z_caption.Visibility = Visibility.Visible;
            tool_z_field.Visibility = Visibility.Visible;
        }

        private void SelectImageTool()
        {
            tool_selection.IsChecked = false;
            tool_text.IsChecked = false;
            tool_image.IsChecked = true;

            tool_separator1.Visibility = Visibility.Visible;

            tool_name_caption.Visibility = Visibility.Visible;
            tool_name_field.Visibility = Visibility.Visible;

            tool_content_caption.Visibility = Visibility.Collapsed;
            tool_content_field.Visibility = Visibility.Collapsed;

            tool_source_caption.Visibility = Visibility.Visible;
            tool_source_field.Visibility = Visibility.Visible;
            tool_source_select.Visibility = Visibility.Visible;

            tool_z_caption.Visibility = Visibility.Visible;
            tool_z_field.Visibility = Visibility.Visible;
        }
    }
}

现在启动应用程序。现在不要尝试调整它的大小,以查看问题!

黄色工具是当前选择的工具。 现在按以下顺序进行: 点击红色按钮:新元素出现。 点击蓝色按钮:一些元素保留,一些元素消失。但奇怪的是缺少一些:“Source:”TexBlock、tool_source_file 文本框和“...”按钮。 尝试调整窗口大小:三个缺失的控件神奇地出现(它们没有出现在工具栏的溢出部分,之前没有激活)

另一种看待问题的方式:

  • 启动应用程序。
  • 黄色工具是当前选择的工具。
  • 点击红色按钮。
  • 点击蓝色按钮。
  • 点击红色按钮。
  • 点击蓝色按钮:三个缺失的控件现在出现在正确的位置!

我的问题很简单:发生了什么事?

我尝试了很多方法,包括在更改项目可见性后使用不同版本的 invalidate 和工具栏,将工具栏分成两个面板等,但没有任何效果。


感谢您的回答。

我很快就会试试你的代码,Tony。

我也在微软网站上提交了这个问题,但显然他们不看建议,除非他们得到 5 票。所以请投票给它:https://connect.microsoft.com/WPF/feedback/details/638552/changing-visibility-of-toolbar-components-to-visible-does-not-make-them-appear-event-in-the-overflow-part-of-the-toolbar#details

问候

【问题讨论】:

  • 我在我的电脑(Win7、.Net 4 SP1 Beta)上复制了这个似乎是一个错误的东西。真的很奇怪。您可以将您的代码和描述提交给connect.microsoft.com,也许他们会指出一个方向或检测到一个 BUG 并尝试在 .Net 4 Final SP1 上包含一个 FIX
  • 是的,绝对看起来像一个错误

标签: c# wpf visibility


【解决方案1】:

我不知道,但这似乎是一个错误。 现在,您可以尝试这样做来解决您的问题:

    private void tool_image_Click(object sender, RoutedEventArgs e)
    {
        SelectImageTool();
        ChangeWidthAndRefresh();  // this call will hopefully make the toolbar to show the correct controls... :)
    }


    // temp workaround for a weird bug. 
    void ChangeWidthAndRefresh()
    {
        var old_Width = this.Width;
        this.Width = old_Width - 1;
        this.Refresh();
        this.Width = old_Width;
        this.Refresh();
    }

注意:Refresh() 方法是我在项目中使用的扩展方法:

// 05-01-2010
public static class WPFUIRefreshExtensionMethods
{
    // www.tonysistemas.com.br
    private static System.Action EmptyDelegate = delegate() { };

    /// <summary>
    /// Força redesenhar
    /// mesmo que esteja dentro de um loop
    /// </summary>
    /// <param name="uiElement"></param>
    public static void Refresh(this System.Windows.UIElement uiElement)
    {
        //uiElement.UpdateLayout();
        uiElement.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, EmptyDelegate);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多