এখানে সমস্ত উত্তর কেবলমাত্র একটি ব্যবহার করে TextBox
বা ম্যানুয়ালি পাঠ্য নির্বাচন প্রয়োগ করার চেষ্টা করছে যা খারাপ কর্মক্ষমতা বা অ-নেটিভ আচরণের দিকে পরিচালিত করে (ঝলকানো ক্যারেটেTextBox
, ম্যানুয়াল বাস্তবায়নে কোনও কীবোর্ড সমর্থন ইত্যাদি) দিকে পরিচালিত করে না)
ঘণ্টার পর ঘণ্টা এবং ডাব্লুপিএফ উত্স কোড পড়ার পরে , পরিবর্তে আমি TextBlock
নিয়ন্ত্রণের (বা অন্য কোনও নিয়ন্ত্রণের) জন্য স্থানীয় ডাব্লুপিএফ পাঠ্য নির্বাচন সক্ষম করার একটি উপায় আবিষ্কার করেছি । পাঠ্য নির্বাচনের প্রায়শই বেশিরভাগ কার্যকারিতা System.Windows.Documents.TextEditor
সিস্টেম শ্রেণিতে প্রয়োগ করা হয় ।
আপনার নিয়ন্ত্রণের জন্য পাঠ্য নির্বাচন সক্ষম করতে আপনার দুটি জিনিস করতে হবে:
TextEditor.RegisterCommandHandlers()
ক্লাস ইভেন্ট হ্যান্ডলারদের রেজিস্টার করতে একবার কল করুন
এর একটি দৃষ্টান্ত তৈরি করুন TextEditor
আপনার বর্গ প্রতিটি নিদর্শনের জন্য এবং আপনার অন্তর্নিহিত উদাহরণস্বরূপ পাস System.Windows.Documents.ITextContainer
এটি
আপনার নিয়ন্ত্রণের Focusable
সম্পত্তি সেট করা আছে এমন একটি প্রয়োজনীয়তাও রয়েছে True
।
এই হল! সহজ মনে হচ্ছে, তবে দুর্ভাগ্যক্রমে TextEditor
শ্রেণিটি অভ্যন্তরীণ হিসাবে চিহ্নিত হয়েছে। সুতরাং এর চারপাশে আমাকে একটি প্রতিবিম্ব র্যাপার লিখতে হয়েছিল:
class TextEditorWrapper
{
private static readonly Type TextEditorType = Type.GetType("System.Windows.Documents.TextEditor, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
private static readonly PropertyInfo IsReadOnlyProp = TextEditorType.GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly PropertyInfo TextViewProp = TextEditorType.GetProperty("TextView", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly MethodInfo RegisterMethod = TextEditorType.GetMethod("RegisterCommandHandlers",
BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(Type), typeof(bool), typeof(bool), typeof(bool) }, null);
private static readonly Type TextContainerType = Type.GetType("System.Windows.Documents.ITextContainer, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
private static readonly PropertyInfo TextContainerTextViewProp = TextContainerType.GetProperty("TextView");
private static readonly PropertyInfo TextContainerProp = typeof(TextBlock).GetProperty("TextContainer", BindingFlags.Instance | BindingFlags.NonPublic);
public static void RegisterCommandHandlers(Type controlType, bool acceptsRichContent, bool readOnly, bool registerEventListeners)
{
RegisterMethod.Invoke(null, new object[] { controlType, acceptsRichContent, readOnly, registerEventListeners });
}
public static TextEditorWrapper CreateFor(TextBlock tb)
{
var textContainer = TextContainerProp.GetValue(tb);
var editor = new TextEditorWrapper(textContainer, tb, false);
IsReadOnlyProp.SetValue(editor._editor, true);
TextViewProp.SetValue(editor._editor, TextContainerTextViewProp.GetValue(textContainer));
return editor;
}
private readonly object _editor;
public TextEditorWrapper(object textContainer, FrameworkElement uiScope, bool isUndoEnabled)
{
_editor = Activator.CreateInstance(TextEditorType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance,
null, new[] { textContainer, uiScope, isUndoEnabled }, null);
}
}
আমি এটি SelectableTextBlock
থেকে উদ্ভূত একটি উত্সও তৈরি করেছি যা TextBlock
উপরে বর্ণিত পদক্ষেপগুলি গ্রহণ করে:
public class SelectableTextBlock : TextBlock
{
static SelectableTextBlock()
{
FocusableProperty.OverrideMetadata(typeof(SelectableTextBlock), new FrameworkPropertyMetadata(true));
TextEditorWrapper.RegisterCommandHandlers(typeof(SelectableTextBlock), true, true, true);
// remove the focus rectangle around the control
FocusVisualStyleProperty.OverrideMetadata(typeof(SelectableTextBlock), new FrameworkPropertyMetadata((object)null));
}
private readonly TextEditorWrapper _editor;
public SelectableTextBlock()
{
_editor = TextEditorWrapper.CreateFor(this);
}
}
আর একটি বিকল্প হ'ল TextBlock
চাহিদা অনুসারে পাঠ্য নির্বাচন সক্ষম করার জন্য একটি সংযুক্ত সম্পত্তি তৈরি করা । এই ক্ষেত্রে, নির্বাচনটি আবার নিষ্ক্রিয় করতে, এই কোডটির TextEditor
প্রতিবিম্ব সমতুল্য ব্যবহার করে একজনকে আলাদা করতে হবে :
_editor.TextContainer.TextView = null;
_editor.OnDetach();
_editor = null;