Mengubah elemen toolbar dari diciutkan menjadi terlihat tidak mengubah visibilitasnya

Saya baru saja menghabiskan sepanjang malam mencoba memahami dan memperbaiki masalah yang saat ini saya temui dengan toolbar:

Saya telah membuat program menggambar berbasis vektor kecil di mana pengguna dapat memilih alat (seleksi, garis, teks, gambar, dll...), dengan mengklik ikon terkait yang terletak di toolbar sebelum menggunakannya.

Ketika alat tertentu dipilih, kontrol baru muncul di toolbar (visibilitasnya, yang awalnya diatur ke diciutkan, diubah menjadi terlihat), memungkinkan pengguna untuk mengubah parameternya.

Misalnya ketika mengklik alat teks, sebuah bidang muncul di mana pengguna dapat menulis konten. Ketika alat gambar dipilih, sebuah tombol muncul yang membuka OpenFileDialog (untuk memilih file sumber), dll...

Masalahnya adalah, dalam situasi yang sangat khusus, beberapa elemen yang seharusnya muncul ketika alat terkait dipilih, tetap tersembunyi, bahkan dengan visibilitasnya disetel ke true dalam kode. Dan kontrol yang hilang juga tidak ada di bagian toolbar yang meluap.

Cukup sulit untuk dijelaskan, jadi berikut adalah contoh kode sumber, yang meniru aplikasi saya dan menunjukkan masalahnya: buat proyek C# wpf baru, lalu salin kode berikut di 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>

And the following lines in the corresponding *.cs file :

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;
        }
    }
}

Sekarang luncurkan aplikasinya. Jangan mencoba mengubah ukurannya sekarang, untuk melihat masalahnya!

Alat berwarna kuning adalah alat yang sedang dipilih. Sekarang lanjutkan dengan urutan ini : Klik tombol merah : elemen baru muncul. Klik pada tombol biru : beberapa elemen tetap ada, beberapa menghilang. Namun anehnya ada beberapa yang hilang: "Sumber:" TexBlock, kotak teks tool_source_file dan tombol "...". Cobalah untuk mengubah ukuran jendela: tiga kontrol yang hilang muncul secara ajaib (mereka tidak ada di bagian toolbar yang meluap, yang sebelumnya tidak aktif)

Cara lain untuk melihat masalahnya:

  • Luncurkan aplikasi.
  • Alat berwarna kuning adalah alat yang sedang dipilih.
  • Klik pada tombol merah.
  • Klik pada tombol biru.
  • Klik pada tombol merah.
  • Klik tombol biru: tiga kontrol yang hilang kini muncul di tempat yang tepat!

Pertanyaan saya sederhana: apa yang terjadi?

Saya telah mencoba banyak hal termasuk menggunakan versi berbeda dari invalidate dengan toolbar setelah mengubah visibilitas item, membagi toolbar menjadi dua panel, dll., tetapi tidak ada yang berhasil.


Terima kasih atas jawaban Anda.

Saya akan segera mencoba kode Anda, Tony.

Saya juga telah menyampaikan masalah ini di situs web Microsoft, tetapi tampaknya mereka tidak menerima saran kecuali mereka mendapat 5 suara. Jadi silakan pilih: https://connect.microsoft.com/WPF/feedback/details/638552/changing-visibility-of-toolbar-components-to-visible-does-not-make-mereka-muncul-acara-di-the-overflow-part-of-the-toolbar#details

Salam


person thomasc    schedule 25.01.2011    source sumber
comment
Saya mereproduksi hal ini yang tampaknya merupakan bug di komputer saya (Win7, .Net 4 SP1 Beta). Sungguh aneh. Anda dapat mengirimkan kode dan deskripsi Anda ke connect.microsoft.com mungkin mereka akan menunjukkan arah atau mendeteksi BUG dan COBA untuk memasukkan FIX untuk itu di .Net 4 Final SP1   -  person Tony    schedule 26.01.2011
comment
ya, pasti terlihat seperti bug   -  person Robert Levy    schedule 26.01.2011


Jawaban (1)


Saya tidak tahu, tapi sepertinya ini bug. Untuk saat ini, Anda dapat mencoba melakukan ini untuk menyelesaikan masalah Anda:

    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();
    }

Catatan: Metode Refresh() adalah metode Ekstensi yang saya gunakan pada proyek saya:

// 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);
    }
}
person Tony    schedule 26.01.2011