سؤال

في مشروعي WPF C#، قمت بإنشاء TreeView.يحتوي كل TreeViewItem على حدث LostFocus الذي يجب رفعه عندما يفقد العنصر تركيزه.لقد قمت أيضًا بإنشاء زر يلزم النقر عليه عندما يريد المستخدم تغيير رأس TreeViewItem معين.يمكن للمستخدم، بعد التحديد في TreeView، النقر فوق الزر وسيظهر TextBox ليحل محل رأس TreeViewItem.إذا لم يقم المستخدم بالنقر فوق TextBox ولكن انقر فوق TreeViewItem آخر، فلن يتم إطلاق الحدث LostFocus أبدًا.بخلاف ذلك، إذا قام المستخدم بالنقر فوق TextBox ثم قام بتغيير التركيز، فسيتم رفعه.لقد استخدمت أيضا textBox.Focus() و Keyboard.Focus(textBox) ولكن لا تعمل.كيف يمكنني اصلاح هذا؟

فقط للتوضيح، قبل إنشاء مشاركة قرأت إجابة SO أخرى هنا

هنا هو رمز المقتطف

 private void RenameButton_Click(object sender, RoutedEventArgs e)
     {

         TreeViewItem twItemSelected = (TreeViewItem)this.Treeview_PropertyDefinition.SelectedItem;                                                            
         var textBox = new TextBox()
         {
             Text = (String)twItemSelected.Header,
         };
         textBox.Focus();
         Keyboard.Focus(textBox);
         if (textBox.IsFocused)
             MessageBox.Show("focused");


         twItemSelected.Header = textBox;            


         //check which property is currently selected

             String parentName = ((TreeViewItem)twItemSelected.Parent).Name;
          ((TreeViewItem)twItemSelected.Parent).Parent).Name;

            //get values from file 
            //show page based on parent value
             switch (parentName)
             {
                 case "RectangleBar_TreeviewItem":
                     textBox.LostFocus += (o, ev) =>
                     {...}  
    }
هل كانت مفيدة؟

المحلول

عفوا لقولي ذلك، ولكن كل مستخدم WPF العادي الذي قرأ سؤالك ربما هز رأسه شفقة.نشعر بالحزن من أجلك لأنك لم تتعلم بعد "Zen of WPF" الحقيقي، وهو الاستفادة من ربط البيانات والقوالب والمشغلات لجعل واجهة المستخدم الخاصة بك ديناميكية بدلاً من القيام بذلك بالطريقة القديمة.WPF جميل بسبب هذه القدرة.كما أنه يجعل الأمور أسهل "بنسبة 1000%".

أنصحك بتغيير واجهة المستخدم الخاصة بك لاستخدام مشغل على TreeViewItem الخاص بك لاستبدال HeaderTemplate الخاص بك بناءً على خاصية تحددها في TreeViewItem.قم بتعيين هذه الخاصية على "صحيح" عند النقر فوق العنصر نقرًا مزدوجًا.اضبطه على خطأ عندما يصبح IsKeyboardFocusWithin خطأ (يمكنك تجاوز البيانات التعريفية وإضافة PropertyChangedCallback لهذا الغرض).

بقدر ما لديك LostFocus تستمر المشكلة، أظن أن مشكلتك تكمن في أن لديك نطاقات تركيز متعددة.

تفاصيل إضافية حول القيام بذلك "بطريقة WPF"

فيما يلي بعض التفاصيل حول كيفية تنفيذ ذلك باستخدام خاصية ومشغلات وقوالب مرفقة.

يمكن أن تكون القوالب الخاصة بك بسيطة أو معقدة كما تريد.هنا بسيط:

<DataTemplate x:Key="NormalTemplate">
  <ContentPresenter />
</DataTemplate>

<DataTemplate x:Key="TextBoxTemplate">
  <TextBox Text="{Binding}" />
</DataTemplate>

إليك ما سيبدو عليه أسلوبك:

يمكن إنشاء الخاصية المرفقة "ShowTextBox" في MyWindowClass باستخدام مقتطف "propa" - فقط اكتب "propa" واضغط على علامة التبويب، ثم املأ الفراغات.

لتبديل العنصر لإظهار مربع النص، فقط:

SetShowTextBox(item, true);
To switch it back:

SetShowTextBox(item, false);

يرجى محاولة التعلم والاستثمار في أنماط وممارسات WPF بحيث يكون من السهل عليك أن تفعل ما تريد تحقيقه.

هناك أيضًا مشاريع يمكن أن تساعدك على البدء بما تريد تحقيقه باستخدام TreeViews.

مشروع عينة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top