हम ListBox
के SelectedItem
को प्रोग्रामेटिक रूप से सेट करना चाहते हैं और उस आइटम को तब ध्यान केंद्रित करना चाहते हैं ताकि तीर कुंजियां उस चयनित आइटम से संबंधित हों। काफी सरल लगता है।आप एक WPF ListBox में चयनित इटैम पर प्रोग्रामेटिक रूप से फ़ोकस कैसे सेट करते हैं जो पहले से ही फोकस कर रहा है?
समस्या लेकिन यदि ListBox
पहले से ही जब SelectedItem
प्रोग्राम के रूप में स्थापित करने, जबकि इसे ठीक से ListBoxItem
पर IsSelected
संपत्ति को अद्यतन करता है कुंजीपटल ध्यान केंद्रित किया जाता है, यह नहीं सेट पर, कीबोर्ड इसे करने के लिए, और इस प्रकार, तीर कुंजी सूची में पहले केंद्रित आइटम के सापेक्ष स्थानांतरित करें, न कि नव-चयनित आइटम की अपेक्षा करें।
यह उपयोगकर्ता के लिए बहुत भ्रमित है क्योंकि यह कुंजीपटल का उपयोग करते समय चयन को चारों ओर कूदने के लिए दिखाई देता है क्योंकि यह प्रोग्रामेटिक चयन होने से पहले कहां जाता है।
नोट: जैसा कि मैंने कहा, यह केवल तब होता है जब आप SelectedItem
संपत्ति को ListBox
पर सेट करते हैं, जिसमें पहले से ही कीबोर्ड फोकस है। यदि यह नहीं करता है (या यदि यह करता है लेकिन आप छोड़ते हैं, तो वापस आते हैं), जब कीबोर्ड फ़ोकस ListBox
पर वापस आ जाता है, तो सही आइटम के पास अब अपेक्षित कीबोर्ड फ़ोकस होगा।
यहां कुछ समस्या नमूना है जो इस समस्या को दिखा रहा है। इसे प्रदर्शित करने के लिए, कोड चलाएं, सूची में 'सात' का चयन करने के लिए माउस का उपयोग करें (इस प्रकार ListBox
पर फ़ोकस डालें), फिर 'टेस्ट' बटन पर क्लिक करें। अंत में, फोकस आयत प्रकट करने के लिए अपने कीबोर्ड पर 'Alt' कुंजी टैप करें। आप देखेंगे कि यह वास्तव में 'सात' पर भी है और यदि आप ऊपर और नीचे तीरों का उपयोग करते हैं, तो वे उस पंक्ति के सापेक्ष हैं, उपयोगकर्ता के रूप में 'चार' की अपेक्षा नहीं होगी।
ध्यान दें कि मेरे पास Focusable
बटन पर false
पर सेट है क्योंकि इसे दबाते समय फोकस के सूची बॉक्स को लूटने के लिए नहीं है। अगर मेरे पास यह नहीं था, तो ListBox
जब आप बटन पर क्लिक करते हैं तो फोकस खो देंगे, और इस प्रकार, जब फोकसबॉक्स पर फ़ोकस लौटाया जाता है, तो यह सही आइटम पर होगा।
XAML फाइल:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="525" Height="350" WindowStartupLocation="CenterScreen"
Title="MainWindow" x:Name="Root">
<DockPanel>
<Button Content="Test"
DockPanel.Dock="Bottom"
HorizontalAlignment="Left"
Focusable="False"
Click="Button_Click" />
<ListBox x:Name="MainListBox" />
</DockPanel>
</Window>
कोड-पीछे:
using System.Collections.ObjectModel;
using System.Windows;
namespace Test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MainListBox.ItemsSource = new string[]{
"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"
};
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MainListBox.SelectedItem = MainListBox.Items[3];
}
}
}
नोट: कुछ IsSynchronizedWithCurrentItem
उपयोग करने के लिए सुझाव दिया है, लेकिन यह है कि संपत्ति जुड़े का Current
संपत्ति के साथ ListBox
की SelectedItem
सिंक्रनाइज़ करता है राय। यह फोकस से संबंधित नहीं है क्योंकि यह समस्या अभी भी मौजूद है।
हमारे काम के आसपास अस्थायी रूप से कहीं और फोकस सेट करने के लिए है, तो चयनित आइटम निर्धारित करते हैं, तो ध्यान केंद्रित वापस ListBox
करने के लिए सेट है, लेकिन यह हमारे ViewModel
ListBox
खुद के बारे में पता करने के लिए हो रही हम में से undesireable प्रभाव पड़ता है, फिर इस पर निर्भर करता है कि इसमें फोकस है या नहीं, (यानी आप बस 'कहीं और फोकस नहीं करना चाहते हैं, फिर यहां वापस आएं, अगर' यहां 'पर ध्यान केंद्रित नहीं किया गया है, तो आप इसे पहले चुरा लेंगे कहीं और से।) इसके अलावा, आप इसे घोषणात्मक बाइंडिंग के माध्यम से आसानी से संभाल नहीं सकते हैं। यह कहने की जरूरत नहीं है कि यह बदसूरत है।
फिर फिर, 'बदसूरत' जहाजों, तो वहां है।
ContainerFromItem नल वापस लौटाएगा यदि उसके लिए कोई कंटेनर अभी तक उत्पन्न नहीं हुआ है, जो वर्चुअलाइज्ड सूची का मामला है और आइटम ऑफ-स्क्रीन है। इसके अलावा यदि आप बाध्यकारी से मान सेट करने का प्रयास करते हैं तो यह टूट जाता है क्योंकि आपके पास ListBox तक पहुंच नहीं है, न ही आपको चाहिए। (नीचे जारी है ...) – MarqueIV
यहां तक कि एक संलग्न व्यवहार भी समस्याएं उत्पन्न करता है क्योंकि आप चाहते हैं कि नियंत्रण को अंधाधुंध को सूची बॉक्स को इटैम पर सेट न करें जब तक कि ए) नियंत्रण पहले से ही फोकस (परीक्षण करने में आसान) था, और बी) परिवर्तन आया कोड-बैक से (सबक्लास के बिना परीक्षण करने में आसान नहीं है।) अन्यथा आप अनजाने में किसी अन्य नियंत्रण (केस ए) से फोकस चुरा सकते हैं या वर्तमान में फोकस कर सकते हैं (केस बी) जब बहु-चयन मोड में और अचयनित करना एक पंक्ति, जो सामान्य रूप से कीबोर्ड फोकस को बनाए रखना चाहिए, लेकिन इसके बजाय नए चयनित इटैम पर सेट किया जाएगा, यदि कोई हो, तो अजीब व्यवहार हो रहा है। – MarqueIV
असल में, दूसरे विचार पर, मुझे लगता है कि मेरे ऊपर उपरोक्त 'बी' के लिए कार्य-आसपास है। आप जुड़े व्यवहार को बनाते हैं जैसे आपने कहा, लेकिन आप इसे सीधे एक्सएएमएल में सेट नहीं करते हैं। इसके बजाय आप अपने व्यूमोडेल पर एक संपत्ति बनाते हैं और उस पर व्यवहार को बांधते हैं। इस तरह आपको सुनने की आवश्यकता नहीं है (या देखभाल) जो सुन रहा है। फिर, चयनित आइटम को कोड से पीछे सेट करने से ठीक पहले, आप व्यवहार को सक्षम करते हैं, आइटम का चयन करते हैं, फिर व्यवहार को फिर से अक्षम करते हैं। यह उपरोक्त 'बी' को संबोधित करता है। (आपको अभी भी 'ए' की ज़रूरत होगी।) अपना जवाब तब से वोट दे रहा है, हालांकि पूरा नहीं हुआ, मुझे इस पथ से नीचे ले गया। – MarqueIV