ভিউ মডেল থেকে ডাব্লুপিএফ-এ টেক্সটবক্সে ফোকাস সেট করুন


129

আমার দৃষ্টিতে একটি TextBoxএবং একটি Buttonরয়েছে।

এখন আমি বোতামের উপর ক্লিক করে একটি শর্ত পরীক্ষা করছি এবং যদি শর্তটি মিথ্যা হয়ে যায় তবে ব্যবহারকারীর কাছে বার্তা প্রদর্শিত হয় এবং তারপরে আমাকে কার্সারটি TextBoxনিয়ন্ত্রণ করতে হবে।

if (companyref == null)
{
    var cs = new Lipper.Nelson.AdminClient.Main.Views.ContactPanels.CompanyAssociation(); 

    MessageBox.Show("Company does not exist.", "Error", MessageBoxButton.OK,
                    MessageBoxImage.Exclamation);

    cs.txtCompanyID.Focusable = true;

    System.Windows.Input.Keyboard.Focus(cs.txtCompanyID);
}

উপরের কোডটি ভিউমডেলে রয়েছে।

CompanyAssociationদৃশ্য নাম।

তবে কার্সারটি সেট করা যাচ্ছে না TextBox

এক্সামলটি হ'ল:

<igEditors:XamTextEditor Name="txtCompanyID" 
                         KeyDown="xamTextEditorAllowOnlyNumeric_KeyDown"
                         ValueChanged="txtCompanyID_ValueChanged"
                         Text="{Binding Company.CompanyId,
                                        Mode=TwoWay,
                                        UpdateSourceTrigger=PropertyChanged}"
                         Width="{Binding ActualWidth, ElementName=border}"
                         Grid.Column="1" Grid.Row="0"
                         VerticalAlignment="Top"
                         HorizontalAlignment="Stretch"
                         Margin="0,5,0,0"
                         IsEnabled="{Binding Path=IsEditable}"/>

<Button Template="{StaticResource buttonTemp1}"
        Command="{Binding ContactCommand}"
        CommandParameter="searchCompany"
        Content="Search"
        Width="80"
        Grid.Row="0" Grid.Column="2"
        VerticalAlignment="Top"
        Margin="0"
        HorizontalAlignment="Left"
        IsEnabled="{Binding Path=IsEditable}"/>

আপনি যখন caliburn.micro ব্যবহার করছেন এটি এটি একটি দুর্দান্ত সমাধান।
matze8426

উত্তর:


264

আপনার প্রশ্নের উত্তরটি আমাকে তিন ভাগে উত্তর দিন।

  1. আমি ভাবছি আপনার উদাহরণে "cs.txtCompanyID" কী? এটি কি টেক্সটবক্স নিয়ন্ত্রণ? যদি হ্যাঁ, তবে আপনি একটি ভুল পথে আছেন। সাধারণভাবে বলতে গেলে আপনার ভিউমোডেলে ইউআইয়ের কোনও রেফারেন্স পাওয়া ভাল ধারণা নয়। আপনি জিজ্ঞাসা করতে পারেন "কেন?" তবে স্ট্যাকওভারফ্লোতে পোস্ট করা এটি অন্য প্রশ্ন :)।

  2. ফোকাসের সাহায্যে সমস্যাগুলি ট্র্যাক করার সর্বোত্তম উপায় হ'ল ... ডিবাগিং et নেট উত্স কোড। দুষ্টুমি করসি না. এটি আমাকে অনেক বার সাশ্রয় করেছে। । নেট সোর্স কোড ডিবাগিং সক্ষম করতে শন ব্রুকের ব্লগ দেখুন।

  3. অবশেষে, ভিউমোডেল থেকে ফোকাস সেট করতে আমি যে সাধারণ পদ্ধতির ব্যবহার করি তা হ'ল সংযুক্ত বৈশিষ্ট্য। আমি খুব সাধারণ সংযুক্ত সম্পত্তি লিখেছিলাম, যা কোনও ইউআইইলেমেন্টে সেট করা যায়। এবং উদাহরণস্বরূপ এটি ভিউমোডেলের সম্পত্তি "ইসফোকাসড" এর সাথে আবদ্ধ হতে পারে। এটা এখানে:

    public static class FocusExtension
    {
        public static bool GetIsFocused(DependencyObject obj)
        {
            return (bool) obj.GetValue(IsFocusedProperty);
        }
    
        public static void SetIsFocused(DependencyObject obj, bool value)
        {
            obj.SetValue(IsFocusedProperty, value);
        }
    
        public static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.RegisterAttached(
                "IsFocused", typeof (bool), typeof (FocusExtension),
                new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
    
        private static void OnIsFocusedPropertyChanged(
            DependencyObject d, 
            DependencyPropertyChangedEventArgs e)
        {
            var uie = (UIElement) d;
            if ((bool) e.NewValue)
            {
                uie.Focus(); // Don't care about false values.
            }
        }
    }

    এখন আপনার ভিউতে (এক্সএএমএলতে) আপনি এই ভিউমোডেলে এই সম্পত্তিটি আবদ্ধ করতে পারেন:

    <TextBox local:FocusExtension.IsFocused="{Binding IsUserNameFocused}" />

আশাকরি এটা সাহায্য করবে :). যদি এটি উত্তর # 2 উল্লেখ না করে।

চিয়ার্স।


5
দুর্দান্ত ধারণা। আমাকে এইসুসারনেমফোকসডকে সত্যে সেট করা দরকার, তাহলে এই কাজটি পেতে আবারও মিথ্যা, এটি কি ঠিক?
স্যাম

19
আপনার নিয়ন্ত্রণটি কী-বোর্ড ফোকাসের পাশাপাশি লজিকাল ফোকাসটি পেতে চান যদি Keyboard.Focus(uie);আপনার OnIsFocusedPropertyChangedইভেন্ট থেকেও কল করা উচিত
রাচেল

6
এটি কীভাবে ব্যবহার করার কথা? যদি আমি আমার সম্পত্তিটিকে সত্যে সেট করি তবে নিয়ন্ত্রণটি কেন্দ্রীভূত। আমি যখন এই দৃশ্যে ফিরে আসি তবে এটি সর্বদা আবার কেন্দ্রীভূত হবে। এটিআইএনএসফোকাসডপ্রোপার্টিচেনজড থেকে পুনরায় সেট করা এটি পরিবর্তন করে না। ভিউমোডেল থেকে এটি সেট করার পরে এটিকে পুনরায় সেট করা আর কোনও কিছুতেই মনোযোগ দেয় না। এটি কাজ করে না। এই up০ জন আপওয়ার সঠিকভাবে কী করেছে?
ygoe

4
আমি ...if ((bool)e.NewValue && uie.Dispatcher != null) { uie.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => uie.Focus())); // invoke behaves nicer, if e.g. you have some additional handler attached to 'GotFocus' of UIE. uie.SetValue(IsFocusedProperty, false); // reset bound value if possible, to allow setting again ... এইটিতে কলব্যাকটিও পরিবর্তন করেছি: মাঝে মাঝে আমাকে ফোকাসটি একাধিকবার সেট করতে চাইলে ভিউমোডলে 'ইসফোকাসড'টিকে মিথ্যাতে পুনরায় সেট করতে হয়। তবে তারপরে এটি কাজ করে, যেখানে অন্য কয়েকটি পদ্ধতি ব্যর্থ হয়েছিল।
সাইমন ডি

3
আপনি ফোকাস সেট করার পরে এবং অন্য একটি নিয়ন্ত্রণ ফোকাস পাওয়ার পরে, ফোকাসটি আবার সেট করতে কাজ করবে না কারণ ইসফোকাস এখনও সত্য। এটিকে মিথ্যা এবং তারপরে সত্যে জোর করা দরকার। public bool IsFocused { get { return _isFocused; } set { if (_isFocused == value) { _isFocused = false; OnPropertyChanged(); } _isFocused = value; OnPropertyChanged(); } }
ওয়াল্টারহুয়াং

75

আমি জানি এই প্রশ্নের উত্তরে এখন পর্যন্ত হাজার বার উত্তর দেওয়া হয়েছে, তবে আমি আনভাকার অবদানের জন্য কিছু সম্পাদনা করেছি যা আমি মনে করি যে আমার সাথে একই রকম সমস্যা রয়েছে এমন অন্যদের সহায়তা করবে I

প্রথমত, আমি উপরের মতো সংযুক্ত সম্পত্তিটি পরিবর্তন করেছি:

public static class FocusExtension
{
    public static readonly DependencyProperty IsFocusedProperty = 
        DependencyProperty.RegisterAttached("IsFocused", typeof(bool?), typeof(FocusExtension), new FrameworkPropertyMetadata(IsFocusedChanged){BindsTwoWayByDefault = true});

    public static bool? GetIsFocused(DependencyObject element)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }

        return (bool?)element.GetValue(IsFocusedProperty);
    }

    public static void SetIsFocused(DependencyObject element, bool? value)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }

        element.SetValue(IsFocusedProperty, value);
    }

    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var fe = (FrameworkElement)d;

        if (e.OldValue == null)
        {
            fe.GotFocus += FrameworkElement_GotFocus;
            fe.LostFocus += FrameworkElement_LostFocus;
        }

        if (!fe.IsVisible)
        {
            fe.IsVisibleChanged += new DependencyPropertyChangedEventHandler(fe_IsVisibleChanged);
        }

        if ((bool)e.NewValue)
        {
            fe.Focus();
        }
    }

    private static void fe_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var fe = (FrameworkElement)sender;
        if (fe.IsVisible && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
        {
            fe.IsVisibleChanged -= fe_IsVisibleChanged;
            fe.Focus();
        }
    }

    private static void FrameworkElement_GotFocus(object sender, RoutedEventArgs e)
    {
        ((FrameworkElement)sender).SetValue(IsFocusedProperty, true);
    }

    private static void FrameworkElement_LostFocus(object sender, RoutedEventArgs e)
    {
        ((FrameworkElement)sender).SetValue(IsFocusedProperty, false);
    }
}

দৃশ্যমানতার উল্লেখগুলি যুক্ত করার জন্য আমার কারণটি ছিল ট্যাব। স্পষ্টতই যদি আপনি প্রাথমিকভাবে দৃশ্যমান ট্যাবের বাইরে অন্য কোনও ট্যাবে সংযুক্ত সম্পত্তি ব্যবহার করেন তবে আপনি নিজে নিজে নিয়ন্ত্রণ নিয়ন্ত্রণ না করা পর্যন্ত সংযুক্ত সম্পত্তি কাজ করবে না।

অন্য বাধা অন্তর্নিহিত সম্পত্তিটিকে ফোকাস হারিয়ে ফেললে এটি মিথ্যাতে পুনরায় সেট করার আরও মার্জিত উপায় তৈরি করছিল। এখানেই হারানো ফোকাস ইভেন্টগুলি এসেছিল।

<TextBox            
    Text="{Binding Description}"
    FocusExtension.IsFocused="{Binding IsFocused}"/>

যদি দৃশ্যমানতার সমস্যাটি হ্যান্ডেল করার আরও ভাল উপায় থাকে তবে দয়া করে আমাকে জানান।

দ্রষ্টব্য: DependencyProperty- এ BindsTwoWayByDefault স্থাপনের পরামর্শের জন্য অ্যাপেলকুয়াচাকে ধন্যবাদ। আমি অনেক আগে নিজের কোডে এটি করেছিলাম, তবে এই পোস্টটি কখনই আপডেট হয়নি। মোড = টু ওয়ে এই পরিবর্তনের কারণে ডাব্লুপিএফ কোডে আর প্রয়োজন নেই।


9
এটি আমার পক্ষে ভাল কাজ করে, যদি আমার ইউজারকন্ট্রোলটিতে ব্যবহৃত হয় তবে গটফোকস / লস্টফোকাসে "যদি (ই। উত্স == ই.আরগিনালসোর্স)" যোগ করা দরকার বা অন্যথায় এটি স্ট্যাকওভারফ্লোস (আক্ষরিকভাবে) যুক্ত করা দরকার যা ফোকাসটিকে অভ্যন্তরীণে পুনঃনির্দেশিত করে উপাদান. আমি দৃশ্যমান চেকগুলি অপসারণ করেছি, এটি ঠিক .ফোকাস () পদ্ধতির মতো কাজ করে accepting যদি .ফোকাস () কাজ না করে তবে বাঁধাইয়ের কাজ করা উচিত নয় - এবং এটি আমার দৃশ্যের জন্য ঠিক।
হ্যালোসাম

1
আমি ডাব্লুএফ 4.5 এ ব্যবহার করছি। ইসফোকাসড চেঞ্জড এ আমার একটি দৃশ্য আছে (একটি ক্রিয়াকলাপটি আবার লোড হয়ে যায়) যেখানে e.NewVueue নাল এবং একটি ব্যতিক্রম ছুঁড়ে ফেলেছে তাই প্রথমে এটি পরীক্ষা করে দেখুন। এই সামান্য পরিবর্তনটি দিয়ে সবকিছু ঠিকঠাক কাজ করে।
ওলারু মিরসিয়া

1
ধন্যবাদ এই ডাব্লুপ্রিকস গ্রেট :) আমি কেবলমাত্র 'ফ্রেমওয়ার্কপ্রোপার্টিমেটাডাটা'-তে' ফ্রেমওয়ার্কপ্রপ্রেটিমেটাডাটা'-তে '{BindsTwoWayByDefault = true added' যুক্ত করেছি যাতে প্রতিটি
বাঁধাইয়ের

1
আমি বুঝতে পারি এটি একটি পুরানো উত্তর, তবে আমি এমন পরিস্থিতিতে চলে যাচ্ছি যেখানে নিয়ন্ত্রণের ইসইনেবলড সম্পত্তিটি আমি ফোকাসটি স্থানান্তর করতে চাই একটি মাল্টি-ভ্যালু কনভার্টারের সাথে আবদ্ধ। স্পষ্টতই, গটফোকাস ইভেন্ট হ্যান্ডলারটি মাল্টি-ভ্যালু রূপান্তরকারী হওয়ার আগে কল হয়ে যায় ... যার অর্থ নিয়ন্ত্রণ, সেই সময়ে, অক্ষম করা হয়, সুতরাং গটফোকাস সম্পূর্ণ হওয়ার সাথে সাথে লস্টফোকাস ডেকে আনে (আমার ধারণা কারণ নিয়ন্ত্রণটি এখনও অক্ষম রয়েছে) । কিভাবে এটি পরিচালনা করতে কোন চিন্তা?
মার্ক ওলবার্ট

1
@ মার্ক অলবার্ট ব্যবহার করুন fe.Dispatcher.BeginInvoke(new Action(() => { fe.Focus(); }), DispatcherPriority.Loaded);যে এটি লোড হওয়ার পরে এটি আপডেট হয়। এখানে আরও তথ্য: টেলিরিক.com
forums

32

আমি মনে করি সবচেয়ে ভাল উপায় হ'ল এমভিভিএম নীতিটি পরিষ্কার রাখা, সুতরাং মূলত আপনাকে অবশ্যই এমভিভিএম লাইট সরবরাহিত মেসেঞ্জার ক্লাসটি ব্যবহার করতে হবে এবং এটি কীভাবে ব্যবহার করবেন তা এখানে:

আপনার ভিউমডেলে (উদাহরণ ভিউমোডেল.cs): নীচে লিখুন

 Messenger.Default.Send<string>("focus", "DoFocus");

এখন আপনার View.cs এ (XAML the view.xaml.cs নয়) নির্মাতায় নিম্নলিখিত লিখুন

 public MyView()
        {
            InitializeComponent();

            Messenger.Default.Register<string>(this, "DoFocus", doFocus);
        }
        public void doFocus(string msg)
        {
            if (msg == "focus")
                this.txtcode.Focus();
        }

এই পদ্ধতিটি ঠিক জরিমানা এবং কম কোড এবং এমভিভিএম মান বজায় রাখার জন্য owাকার


9
ভাল আপনি যদি এমভিভিএম নীতিটি পরিষ্কার রাখতে চান তবে আপনার কোডটিতে কোডটি প্রথম স্থানে রাখবেন না। আমি বিশ্বাস করি যে সংযুক্ত সম্পত্তির পদ্ধতিটি আরও পরিষ্কার। এটি আপনার ভিউ মডেলের পাশাপাশি প্রচুর যাদু স্ট্রিংগুলি প্রবর্তন করে না।
Г И І И О

32
এল নিনো: আপনার ধারণা কোডের পিছনে কোনও কিছু থাকা উচিত নয় এমন ধারণাটি আপনি ঠিক কোথায় পেয়েছেন? ইউআই-সম্পর্কিত যে কোনও কিছুই ভিউ-কোডের পিছনে থাকা উচিত। ইউআই উপাদানগুলির ফোকাস সেট করা অবশ্যই দৃশ্যের সাথে কোডের পিছনে থাকা উচিত। বার্তাটি কখন প্রেরণ করতে হবে তা ভিউমোডেলকে খুঁজে বের করতে দিন; বার্তাটি দিয়ে কী করা যায় তা দৃশ্যকে বুঝতে দিন। এমভি-ভিএম এটিই করে: ডেটা মডেল, ব্যবসায় যুক্তি এবং ইউআইয়ের উদ্বেগগুলি পৃথক করে।
কাইল হ্যালে

এই পরামর্শের উপর ভিত্তি করে, আমি আমার নিজস্ব ভিউকম্যান্ডম্যানেজারটি প্রয়োগ করেছি যা সংযুক্ত ভিউগুলিতে আমন্ত্রণকারী আদেশগুলি পরিচালনা করে। এটি মূলত নিয়মিত কমান্ডের অন্য দিক, এই ক্ষেত্রেগুলির জন্য যখন কোনও ভিউমোডেল তার ভিউ (গুলি) তে কিছু পদক্ষেপ নেয়। এটি মেমরি ফাঁস এড়ানোর জন্য ডেটা-বাউন্ড কমান্ড এবং WeakReferences এর মতো প্রতিবিম্ব ব্যবহার করে। dev.unclassified.de/source/viewcommand ( কোডপ্রজেক্টেও )
ygoe

আমি এই পদ্ধতিটি ডাব্লুপিএফ ফ্লোডোকুমেন্টগুলি মুদ্রণের জন্য ব্যবহার করেছি। সুন্দরভাবে কাজ করেছেন। ধন্যবাদ
গর্ডন স্লাইজ

আমি সিলভারলাইটে একটি চাই? আমরা কি এটি ব্যবহার করতে পারি?
বিগিয়েস

18

এগুলির কোনওটিই আমার পক্ষে ঠিক কাজ করেনি, তবে অন্যের উপকারের জন্য, আমি এখানে ইতিমধ্যে সরবরাহ করা কিছু কোডের ভিত্তিতে লেখাটি শেষ করেছি।

ব্যবহার নিম্নরূপ হবে:

<TextBox ... h:FocusBehavior.IsFocused="True"/>

এবং বাস্তবায়ন নিম্নলিখিত হবে:

/// <summary>
/// Behavior allowing to put focus on element from the view model in a MVVM implementation.
/// </summary>
public static class FocusBehavior
{
    #region Dependency Properties
    /// <summary>
    /// <c>IsFocused</c> dependency property.
    /// </summary>
    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached("IsFocused", typeof(bool?),
            typeof(FocusBehavior), new FrameworkPropertyMetadata(IsFocusedChanged));
    /// <summary>
    /// Gets the <c>IsFocused</c> property value.
    /// </summary>
    /// <param name="element">The element.</param>
    /// <returns>Value of the <c>IsFocused</c> property or <c>null</c> if not set.</returns>
    public static bool? GetIsFocused(DependencyObject element)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }
        return (bool?)element.GetValue(IsFocusedProperty);
    }
    /// <summary>
    /// Sets the <c>IsFocused</c> property value.
    /// </summary>
    /// <param name="element">The element.</param>
    /// <param name="value">The value.</param>
    public static void SetIsFocused(DependencyObject element, bool? value)
    {
        if (element == null)
        {
            throw new ArgumentNullException("element");
        }
        element.SetValue(IsFocusedProperty, value);
    }
    #endregion Dependency Properties

    #region Event Handlers
    /// <summary>
    /// Determines whether the value of the dependency property <c>IsFocused</c> has change.
    /// </summary>
    /// <param name="d">The dependency object.</param>
    /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Ensure it is a FrameworkElement instance.
        var fe = d as FrameworkElement;
        if (fe != null && e.OldValue == null && e.NewValue != null && (bool)e.NewValue)
        {
            // Attach to the Loaded event to set the focus there. If we do it here it will
            // be overridden by the view rendering the framework element.
            fe.Loaded += FrameworkElementLoaded;
        }
    }
    /// <summary>
    /// Sets the focus when the framework element is loaded and ready to receive input.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
    private static void FrameworkElementLoaded(object sender, RoutedEventArgs e)
    {
        // Ensure it is a FrameworkElement instance.
        var fe = sender as FrameworkElement;
        if (fe != null)
        {
            // Remove the event handler registration.
            fe.Loaded -= FrameworkElementLoaded;
            // Set the focus to the given framework element.
            fe.Focus();
            // Determine if it is a text box like element.
            var tb = fe as TextBoxBase;
            if (tb != null)
            {
                // Select all text to be ready for replacement.
                tb.SelectAll();
            }
        }
    }
    #endregion Event Handlers
}

11

এটি একটি পুরানো থ্রেড, তবে কোডের সাথে এমন কোনও উত্তর বলে মনে হচ্ছে না যা আনভঙ্কার গৃহীত উত্তরের সাথে সমস্যাগুলি সম্বোধন করবে: আপনি ভিউ মডেলটিতে সম্পত্তিটি মিথ্যা হিসাবে সেট করলে বা আপনার সম্পত্তি সেট করা থাকলে এটি কার্যকর হয় না or সত্য, ব্যবহারকারী ম্যানুয়ালি অন্য কোনও কিছুতে ক্লিক করে এবং তারপরে আপনি এটি আবার সত্যতে সেট করেন। আমি এই ক্ষেত্রেও নির্ভরযোগ্যভাবে কাজ করার জন্য জামোটিকের সমাধান পেতে পারি না।

উপরের কয়েকটি আলোচনার একসাথে টানা আমাকে নীচের কোডটি দেয় যা আমার মনে হয় এই সমস্যাগুলির সমাধান করে:

public static class FocusExtension
{
    public static bool GetIsFocused(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsFocusedProperty);
    }

    public static void SetIsFocused(DependencyObject obj, bool value)
    {
        obj.SetValue(IsFocusedProperty, value);
    }

    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached(
         "IsFocused", typeof(bool), typeof(FocusExtension),
         new UIPropertyMetadata(false, null, OnCoerceValue));

    private static object OnCoerceValue(DependencyObject d, object baseValue)
    {
        if ((bool)baseValue)
            ((UIElement)d).Focus();
        else if (((UIElement) d).IsFocused)
            Keyboard.ClearFocus();
        return ((bool)baseValue);
    }
}

এই বলে যে, এটি এখনও এমন কোনও কিছুর জন্য জটিল যা কোডবিহাইডে এক লাইনে করা যেতে পারে, এবং কোরেসারভ্যালু সত্যিকার অর্থে এইভাবে ব্যবহার করা উচিত নয়, তাই সম্ভবত কোডবিহাইন্ড যাওয়ার উপায়।


1
এটি ধারাবাহিকভাবে কাজ করে, যেখানে গৃহীত উত্তর দেয় না। ধন্যবাদ!
নাথানআল্ডেনএসআর

4

আমার ক্ষেত্রে, আমি অনআইএসফোকাসডপ্রোপার্টিচেনজড পদ্ধতিটি পরিবর্তন না করা পর্যন্ত ফোকাস এক্সটেনশন কাজ করে না। আসলটি কেবলমাত্র ডিবাগে কাজ করছিল যখন ব্রেক ব্রেকটি প্রক্রিয়াটি বন্ধ করে দেয়। রানটাইমের সময়, প্রক্রিয়াটি খুব দ্রুত এবং কিছুই সুখী হয় না। এই সামান্য পরিবর্তন এবং আমাদের বন্ধু টাসকের সহায়তায়, এটি উভয় পরিস্থিতিতেই ঠিকঠাক কাজ করছে।

private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  var uie = (UIElement)d;
  if ((bool)e.NewValue)
  {
    var action = new Action(() => uie.Dispatcher.BeginInvoke((Action)(() => uie.Focus())));
    Task.Factory.StartNew(action);
  }
}

3

সমস্যাটি হ'ল একবার আইসউজারনেমফোকাসটি সত্যতে সেট হয়ে গেলে এটি কখনই মিথ্যা হবে না। এটি ফ্রেমওয়ার্ক এলিমেন্টের জন্য গটফোকাস এবং লস্টফোকাস পরিচালনা করে এটি সমাধান করে।

উত্স কোড ফর্ম্যাট করতে আমার সমস্যা হয়েছিল তাই এখানে একটি লিঙ্ক is


1
আমি "অবজেক্ট ফে = (ফ্রেমওয়ার্কএলমেন্ট) ডি;" চেঞ্জ করেছি; " "ফ্রেমওয়ার্কএলমেন্ট ফে = (ফ্রেমওয়ার্কএলমেন্ট) ডি;" সুতরাং

তবুও সমস্যার সমাধান হয় না। আমি যখনই ফিরে আসি ততক্ষণে উপাদানটি মনোনিবেশিত থাকে।
ygoe

3

আনওয়াকাস উজ্জ্বল কোডটি উইন্ডোজ ডেস্কটপ অ্যাপ্লিকেশনগুলির জন্য। আপনি যদি আমার মতো হন এবং উইন্ডোজ স্টোর অ্যাপ্লিকেশনগুলির জন্য একই সমাধানের প্রয়োজন হয় তবে এই কোডটি কার্যকর হতে পারে:

public static class FocusExtension
{
    public static bool GetIsFocused(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsFocusedProperty);
    }


    public static void SetIsFocused(DependencyObject obj, bool value)
    {
        obj.SetValue(IsFocusedProperty, value);
    }


    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached(
         "IsFocused", typeof(bool), typeof(FocusExtension),
         new PropertyMetadata(false, OnIsFocusedPropertyChanged));


    private static void OnIsFocusedPropertyChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            var uie = d as Windows.UI.Xaml.Controls.Control;

            if( uie != null )
            {
                uie.Focus(FocusState.Programmatic);
            }
        }
    }
}

1

উপরের দিকে আনভাকার সমাধানটি ব্যবহার করার চেষ্টা করা লোকদের জন্য, আমি প্রথমবারের সাথে বন্ডিংয়ের সাথে সমস্যা নিয়েই ছিলাম, কারণ হারিয়ে যাওয়া ফোকাস সম্পত্তিটিকে মিথ্যা হিসাবে আপডেট করবে না। আপনি নিজেই সম্পত্তিটিকে মিথ্যা এবং তারপর প্রতিটি সময় সত্য হিসাবে সেট করতে পারেন, তবে আপনার সম্পত্তিতে এরকম কিছু করার থেকে আরও ভাল সমাধান হতে পারে:

bool _isFocused = false;
    public bool IsFocused 
    {
        get { return _isFocused ; }
        set
        {
            _isFocused = false;
            _isFocused = value;
            base.OnPropertyChanged("IsFocused ");
        }
    }

এইভাবে আপনার কেবল কখনও এটি সত্যে সেট করা দরকার এবং এটি ফোকাস পাবে।


আপনি যদি একটি বিবৃতি আছে? একবারে মিথ্যাতে সেট করা _আইসফোকাসটি কেবল পরের লাইনেই মানটিতে পরিবর্তিত হবে।
ড্যামিয়েন ম্যাকগাইভার

1
@ টায়ারিয়াস আপনি কোরেসে নির্ভরতার সম্পত্তি পেয়ে এই সমস্যাটি সমাধান করতে পারেন, এখানে দেখুন- social.msdn.microsoft.com/ Forums
en-

1

আমি ডাব্লুপিএফ / ক্যালিবার্ন মাইক্রো ব্যবহার করে দেখেছি যে "ডিফাইভ্রে" এখানে একটি সাধারণ এবং কার্যক্ষম সমাধান সমাধান করেছে: http://caliburnmicro.codeplex.com/discussion/222892


1

নিম্নলিখিত হিসাবে কোড সম্পাদনা করে সমাধান পেয়েছি। বাঁধার সম্পত্তি প্রথমে মিথ্যা তারপর সত্য বলে সেট করার দরকার নেই।

public static class FocusExtension
{

    public static bool GetIsFocused(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsFocusedProperty);
    }


    public static void SetIsFocused(DependencyObject obj, bool value)
    {
        obj.SetValue(IsFocusedProperty, value);
    }


    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached(
         "IsFocused", typeof(bool), typeof(FocusExtension),
         new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));


    private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d != null && d is Control)
        {
            var _Control = d as Control;
            if ((bool)e.NewValue)
            {
                // To set false value to get focus on control. if we don't set value to False then we have to set all binding
                //property to first False then True to set focus on control.
                OnLostFocus(_Control, null);
                _Control.Focus(); // Don't care about false values.
            }
        }
    }

    private static void OnLostFocus(object sender, RoutedEventArgs e)
    {
        if (sender != null && sender is Control)
        {
            (sender as Control).SetValue(IsFocusedProperty, false);
        }
    }
}

0

সিলভারলাইটের জন্য:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace MyProject.Behaviors
{
    public class FocusBehavior : Behavior<Control>
    {
        protected override void OnAttached()
        {
            this.AssociatedObject.Loaded += AssociatedObject_Loaded;
            base.OnAttached();
        }

        private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
        {
            this.AssociatedObject.Loaded -= AssociatedObject_Loaded;
            if (this.HasInitialFocus || this.IsFocused)
            {
                this.GotFocus();
            }
        }

        private void GotFocus()
        {
            this.AssociatedObject.Focus();
            if (this.IsSelectAll)
            {
                if (this.AssociatedObject is TextBox)
                {
                    (this.AssociatedObject as TextBox).SelectAll();
                }
                else if (this.AssociatedObject is PasswordBox)
                {
                    (this.AssociatedObject as PasswordBox).SelectAll();
                }
                else if (this.AssociatedObject is RichTextBox)
                {
                    (this.AssociatedObject as RichTextBox).SelectAll();
                }
            }
        }

        public static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.Register(
                "IsFocused",
                typeof(bool),
                typeof(FocusBehavior),
                new PropertyMetadata(false, 
                    (d, e) => 
                    {
                        if ((bool)e.NewValue)
                        {
                            ((FocusBehavior)d).GotFocus();
                        }
                    }));

        public bool IsFocused
        {
            get { return (bool)GetValue(IsFocusedProperty); }
            set { SetValue(IsFocusedProperty, value); }
        }

        public static readonly DependencyProperty HasInitialFocusProperty =
            DependencyProperty.Register(
                "HasInitialFocus",
                typeof(bool),
                typeof(FocusBehavior),
                new PropertyMetadata(false, null));

        public bool HasInitialFocus
        {
            get { return (bool)GetValue(HasInitialFocusProperty); }
            set { SetValue(HasInitialFocusProperty, value); }
        }

        public static readonly DependencyProperty IsSelectAllProperty =
            DependencyProperty.Register(
                "IsSelectAll",
                typeof(bool),
                typeof(FocusBehavior),
                new PropertyMetadata(false, null));

        public bool IsSelectAll
        {
            get { return (bool)GetValue(IsSelectAllProperty); }
            set { SetValue(IsSelectAllProperty, value); }
        }

    }
}

LoginViewModel.cs:

    public class LoginModel : ViewModelBase
    {
        ....

        private bool _EmailFocus = false;
        public bool EmailFocus
        {
            get
            {
                return _EmailFocus;
            }
            set
            {
                if (value)
                {
                    _EmailFocus = false;
                    RaisePropertyChanged("EmailFocus");
                }
                _EmailFocus = value;
                RaisePropertyChanged("EmailFocus");
            }
        }
       ...
   }

Login.xaml:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:beh="clr-namespace:MyProject.Behaviors"

<TextBox Text="{Binding Email, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <i:Interaction.Behaviors>
        <beh:FocusBehavior IsFocused="{Binding EmailFocus}" IsSelectAll="True"/>
    </i:Interaction.Behaviors>
</TextBox>

অথবা

<TextBox Text="{Binding Email, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <i:Interaction.Behaviors>
        <beh:FocusBehavior HasInitialFocus="True" IsSelectAll="True"/>
    </i:Interaction.Behaviors>
</TextBox>

ফোকাস সেট করার জন্য এটি কোডে করা উচিত:

EmailFocus = true;

মনে রাখবেন যে এই প্লাগইনটি এইচটিএমএল পৃষ্ঠার অংশ, সুতরাং পৃষ্ঠার অন্যান্য নিয়ন্ত্রণগুলিতে ফোকাস থাকতে পারে

if (!Application.Current.IsRunningOutOfBrowser)
{
    System.Windows.Browser.HtmlPage.Plugin.Focus();
}

0

আপনি ভিউকম্যান্ড ডিজাইন প্যাটার্নটি ব্যবহার করতে পারেন । এটি কমান্ড সহ ভিউমোডেল থেকে একটি ভিউ নিয়ন্ত্রণ করার জন্য এমভিভিএম ডিজাইন প্যাটার্নের জন্য একটি পদ্ধতি বর্ণনা করে।

আমি এমভিভিএম লাইট ম্যাসেঞ্জার ক্লাসটি ব্যবহারের কিং এ মজিদের পরামর্শের ভিত্তিতে এটি প্রয়োগ করেছি। ভিউকম্যান্ডম্যানেজার ক্লাস সংযুক্ত ভিউগুলিতে অনুরোধকারী আদেশগুলি পরিচালনা করে। এটি মূলত নিয়মিত কমান্ডের অন্য দিক, এই ক্ষেত্রেগুলির জন্য যখন কোনও ভিউমোডেলকে তার দৃষ্টিতে কিছু ব্যবস্থা নেওয়া প্রয়োজন। এটি মেমরি ফাঁস এড়ানোর জন্য ডেটা-বাউন্ড কমান্ড এবং WeakReferences এর মতো প্রতিবিম্ব ব্যবহার করে।

http://dev.unclassified.de/source/viewcommand (কোডপ্রজেক্টেও প্রকাশিত)


0

বাইন্ডেড ভেরিয়েবলের মাধ্যমে অ্যাট্রিবিউটগুলি আপডেট করা সহজ করার জন্য কেউ চূড়ান্ত পদক্ষেপ অন্তর্ভুক্ত করেছে বলে মনে হয় না। আমি যা নিয়ে এসেছি তা এখানে। এটি করার আরও ভাল উপায় আছে কিনা তা আমাকে জানান।

XAML

    <TextBox x:Name="txtLabel"
      Text="{Binding Label}"
      local:FocusExtension.IsFocused="{Binding txtLabel_IsFocused, Mode=TwoWay}" 
     />

    <Button x:Name="butEdit" Content="Edit"
        Height="40"  
        IsEnabled="{Binding butEdit_IsEnabled}"                        
        Command="{Binding cmdCapsuleEdit.Command}"                            
     />   

ViewModel

    public class LoginModel : ViewModelBase
    {

    public string txtLabel_IsFocused { get; set; }                 
    public string butEdit_IsEnabled { get; set; }                


    public void SetProperty(string PropertyName, string value)
    {
        System.Reflection.PropertyInfo propertyInfo = this.GetType().GetProperty(PropertyName);
        propertyInfo.SetValue(this, Convert.ChangeType(value, propertyInfo.PropertyType), null);
        OnPropertyChanged(PropertyName);
    }                


    private void Example_function(){

        SetProperty("butEdit_IsEnabled", "False");
        SetProperty("txtLabel_IsFocused", "True");        
    }

    }

0

আমার ফোকাস সমস্যাটি সমাধান করার জন্য প্রথমে আমি আভাঙ্কাকে ধন্যবাদ জানাতে চাই। তিনি পোস্ট করা কোডটিতে অবশ্য একটি বাগ রয়েছে, যথা লাইনটিতে: যদি (e.OldValue == নাল)

আমার সমস্যাটি হ'ল আপনি যদি প্রথমে আপনার দৃষ্টিভঙ্গিতে ক্লিক করেন এবং নিয়ন্ত্রণটি ফোকাস করেন তবে e.oldValue আর নাল নয়। তারপরে আপনি যখন প্রথমবার নিয়ন্ত্রণটি ফোকাস করার জন্য ভেরিয়েবলটি সেট করেন, ফলস্বরূপ হ'ল ফোকাস এবং গোটফোকাস হ্যান্ডলারগুলি সেট না করা। আমার এর সমাধানটি নিম্নরূপ ছিল:

public static class ExtensionFocus
    {
    static ExtensionFocus()
        {
        BoundElements = new List<string>();
        }

    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached("IsFocused", typeof(bool?),
        typeof(ExtensionFocus), new FrameworkPropertyMetadata(false, IsFocusedChanged));

    private static List<string> BoundElements;

    public static bool? GetIsFocused(DependencyObject element)
        {
        if (element == null)
            {
            throw new ArgumentNullException("ExtensionFocus GetIsFocused called with null element");
            }
        return (bool?)element.GetValue(IsFocusedProperty);
        }

    public static void SetIsFocused(DependencyObject element, bool? value)
        {
        if (element == null)
            {
            throw new ArgumentNullException("ExtensionFocus SetIsFocused called with null element");
            }
        element.SetValue(IsFocusedProperty, value);
        }

    private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        var fe = (FrameworkElement)d;

        // OLD LINE:
        // if (e.OldValue == null)
        // TWO NEW LINES:
        if (BoundElements.Contains(fe.Name) == false)
            {
            BoundElements.Add(fe.Name);
            fe.LostFocus += OnLostFocus;
            fe.GotFocus += OnGotFocus;
            }           


        if (!fe.IsVisible)
            {
            fe.IsVisibleChanged += new DependencyPropertyChangedEventHandler(fe_IsVisibleChanged);
            }

        if ((bool)e.NewValue)
            {
            fe.Focus();             
            }
        }

    private static void fe_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
        var fe = (FrameworkElement)sender;

        if (fe.IsVisible && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
            {
            fe.IsVisibleChanged -= fe_IsVisibleChanged;
            fe.Focus();
            }
        }

    private static void OnLostFocus(object sender, RoutedEventArgs e)
        {
        if (sender != null && sender is Control s)
            {
            s.SetValue(IsFocusedProperty, false);
            }
        }

    private static void OnGotFocus(object sender, RoutedEventArgs e)
        {
        if (sender != null && sender is Control s)
            {
            s.SetValue(IsFocusedProperty, true);
            }
        }
    }

0

শুধু এটি করুন:

<Window x:class...
   ...
   ...
   FocusManager.FocusedElement="{Binding ElementName=myTextBox}"
>
<Grid>
<TextBox Name="myTextBox"/>
...

আমি এই পছন্দ। আপনি যদি প্রাথমিক ফোকাসটি সেট করতে চান তবে এটি ভালভাবে কাজ করে।
ব্যবহারকারীর 2430797

0

গৃহীত উত্তর কার্যকর করার পরে আমি একটি ইস্যু জুড়েছিলাম যে প্রিজম দিয়ে যখন ভিউ নেভিগেট করা হয় তখনও ফোকাস পাওয়া যায় না। প্রপার্টি চেঞ্জড হ্যান্ডলারের একটি সামান্য পরিবর্তন এটি সমাধান করেছে

    private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var uie = (UIElement)d;
        if ((bool)e.NewValue)
        {
            uie.Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
            {
                uie.Focus();
            }));
        }
    }

0

@ শেরিদান উত্তরের উপর ভিত্তি করে একটি বিকল্প পন্থা এখানে

 <TextBox Text="{Binding SomeText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <TextBox.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding SomeTextIsFocused, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="True">
                        <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>

আপনার দৃশ্যে মডেলটি আপনার নিয়মিত পদ্ধতিতে বাঁধাই সেট আপ করে এবং তারপরে আপনার পাঠ্য বাক্সটিতে ফোকাসটি সেট করতে সামার টেক্সটআইফসকে সত্য হিসাবে সেট করে


-1

আমি দেখেছি জটিল IsVisible সমস্যা এর সমাধান খুব দরকারী। এটি সম্পূর্ণরূপে আমার সমস্যার সমাধান করেনি, তবে ইসনেবল প্যাটার্নের জন্য একই প্যাটার্ন অনুসরণ করে কিছু অতিরিক্ত কোড করেছে।

ইসফোকাসড চ্যাঞ্জড পদ্ধতিতে আমি যুক্ত করেছি:

    if (!fe.IsEnabled)
    {
        fe.IsEnabledChanged += fe_IsEnabledChanged;
    }

এবং হ্যান্ডলারটি এখানে:

private static void fe_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    var fe = (FrameworkElement)sender;
    if (fe.IsEnabled && (bool)((FrameworkElement)sender).GetValue(IsFocusedProperty))
    {
        fe.IsEnabledChanged -= fe_IsEnabledChanged;
        fe.Focus();
    }
}

-1
public class DummyViewModel : ViewModelBase
    {
        private bool isfocused= false;
        public bool IsFocused
        {
            get
            {
                return isfocused;
            }
            set
            {
                isfocused= value;
                OnPropertyChanged("IsFocused");
            }
        }
    }

-7
System.Windows.Forms.Application.DoEvents();
Keyboard.Focus(tbxLastName);

1
ওপি ডাব্লুপিএফ ব্যবহার করছে। উইনফর্মগুলির ফোকাস কোড সাহায্য করবে না।
জোশ জি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.