Saya ingin membuat teks ditampilkan di Witty , klien Twitter open source, dapat dipilih. Saat ini ditampilkan menggunakan blok teks khusus. Saya perlu menggunakan TextBlock karena saya bekerja dengan inline textblock untuk menampilkan dan memformat @namapengguna dan tautan sebagai hyperlink. Permintaan yang sering adalah untuk dapat menyalin-menempelkan teks. Untuk melakukan itu saya perlu membuat TextBlock dipilih.
Saya mencoba membuatnya bekerja dengan menampilkan teks menggunakan TextBox read-only yang ditata agar terlihat seperti textblock tetapi ini tidak akan berfungsi dalam kasus saya karena TextBox tidak memiliki inline. Dengan kata lain, saya tidak bisa mendesain atau memformat teks dalam TextBox secara individual seperti saya bisa dengan TextBlock.
Ada ide?
Jawaban:
sumber
Semua jawaban di sini hanya menggunakan
TextBox
atau mencoba menerapkan pemilihan teks secara manual, yang mengarah pada kinerja yang buruk atau perilaku non-pribumi (tanda sisipan berkedipTextBox
, tidak ada dukungan keyboard dalam implementasi manual, dll.)Setelah berjam-jam menggali dan membaca kode sumber WPF , saya malah menemukan cara mengaktifkan pemilihan teks WPF asli untuk
TextBlock
kontrol (atau benar-benar kontrol lain). Sebagian besar fungsi di sekitar pemilihan teks diimplementasikan dalamSystem.Windows.Documents.TextEditor
kelas sistem.Untuk mengaktifkan pemilihan teks untuk kontrol Anda, Anda perlu melakukan dua hal:
Panggil
TextEditor.RegisterCommandHandlers()
sekali untuk mendaftarkan penangan acara kelasBuat instance
TextEditor
untuk setiap instance dari kelas Anda dan berikan instance AndaSystem.Windows.Documents.ITextContainer
untuknyaAda juga persyaratan yang mengatur
Focusable
properti kontrol AndaTrue
.Ini dia! Kedengarannya mudah, tetapi sayangnya
TextEditor
kelas ditandai sebagai internal. Jadi saya harus menulis pembungkus refleksi di sekitarnya:Saya juga membuat
SelectableTextBlock
turunan dariTextBlock
yang mengambil langkah-langkah yang disebutkan di atas:Pilihan lain adalah membuat properti terlampir untuk
TextBlock
memungkinkan pemilihan teks sesuai permintaan. Dalam hal ini, untuk menonaktifkan seleksi lagi, kita perlu melepaskan aTextEditor
dengan menggunakan refleksi setara dari kode ini:sumber
TextBlock
sudah tertanamHyperlink
selamaHyperlink
bukan inline terakhir di dalamnya. Menambahkan trailing blankRun
ke perbaikan konten apa pun masalah yang mendasarinya adalah hasilExecutionEngineException
pelemparan.TextTrimming="CharacterEllipsis"
diTextBlock
dan lebar yang tersedia tidak mencukupi, jika Anda memindahkan pointer mouse di atas ..., itu crash dengan System.ArgumentException "jarak Diminta berada di luar isi dokumen terkait." di System.Windows.Documents.TextPointer.InitializeOffset (posisi TextPointer, jarak Int32, arah LogicalDirection) :( Tidak tahu apakah ada solusi selain meninggalkan TextTrimming diatur ke Tidak ada.Saya tidak dapat menemukan contoh untuk benar-benar menjawab pertanyaan itu. Semua jawaban menggunakan Textbox atau RichTextbox. Saya membutuhkan solusi yang memungkinkan saya untuk menggunakan TextBlock, dan ini adalah solusi yang saya buat.
Saya percaya cara yang benar untuk melakukan ini adalah memperluas kelas TextBlock. Ini adalah kode yang saya gunakan untuk memperluas kelas TextBlock untuk memungkinkan saya memilih teks dan menyalinnya ke clipboard. "sdo" adalah referensi namespace yang saya gunakan di WPF.
WPF Menggunakan Extended Class:
Kode di Belakang untuk Kelas Lanjutan:
Contoh Jendela Kode:
sumber
Terapkan gaya ini ke TextBox Anda dan hanya itu (terinspirasi dari artikel ini ):
sumber
Buat ControlTemplate untuk TextBlock dan letakkan TextBox di dalamnya dengan set properti readonly. Atau cukup gunakan TextBox dan buat hanya dibaca, maka Anda dapat mengubah TextBox. Gaya untuk membuatnya tampak seperti TextBlock.
sumber
Saya tidak yakin apakah Anda dapat membuat TextBlock dapat dipilih, tetapi opsi lain adalah menggunakan RichTextBox - ini seperti TextBox seperti yang Anda sarankan, tetapi mendukung pemformatan yang Anda inginkan.
sumber
Menurut Windows Dev Center :
sumber
Sementara pertanyaannya memang mengatakan 'Dapat Dipilih' Saya percaya hasil yang disengaja adalah untuk mendapatkan teks ke clipboard. Ini dapat dengan mudah dan elegan dicapai dengan menambahkan Menu Konteks dan item menu yang disebut salinan yang menempatkan nilai properti Textblock Text di clipboard. Hanya sebuah ide.
sumber
TextBlock tidak memiliki templat. Jadi untuk mencapai ini, kita perlu menggunakan TextBox yang gayanya diubah untuk berperilaku sebagai textBlock.
sumber
Ada solusi alternatif yang mungkin dapat disesuaikan dengan RichTextBox yang disediakan dalam posting blog ini - ini menggunakan pemicu untuk menukar templat kontrol saat penggunaan melayang di atas kontrol - akan membantu kinerja
sumber
sumber
Menambahkan ke jawaban @ torvin dan sebagai @ David Huang disebutkan dalam komentar jika Anda telah
TextTrimming="CharacterEllipsis"
mengaktifkan aplikasi crash ketika Anda mengarahkan kursor ke elipsis.Saya mencoba opsi lain yang disebutkan di utas tentang menggunakan TextBox tapi itu benar-benar tampaknya tidak menjadi solusi baik karena tidak menunjukkan 'ellipsis' dan juga jika teks terlalu panjang untuk muat wadah memilih konten dari kotak teks 'gulir' secara internal yang bukan merupakan perilaku TextBlock.
Saya pikir solusi terbaik adalah jawaban @ torvin tetapi memiliki crash jahat ketika melayang di atas ellipsis.
Saya tahu ini tidak cantik, tetapi berlangganan / berhenti berlangganan secara internal untuk pengecualian yang tidak ditangani dan menangani pengecualian adalah satu-satunya cara yang saya temukan untuk menyelesaikan masalah ini, silakan bagikan jika seseorang memiliki solusi yang lebih baik :)
sumber
Saya telah mengimplementasikan SelectableTextBlock di pustaka kontrol opensource saya. Anda bisa menggunakannya seperti ini:
sumber
sumber
Saya membawa beberapa modifikasi kecil
sumber