question

ArliChokoev-9898 avatar image
0 Votes"
ArliChokoev-9898 asked DaisyTian-1203 answered

UserControl bindings before loaded

I'm trying to focus different elements of control when it's created, based on some variables in view model. For this I registered an additional property in code behind and bound it:

 public static readonly DependencyProperty FocusArticlesOnStartProperty = DependencyProperty.Register("FocusArticlesOnStart",
      typeof(bool), typeof(ChargeCreate), new PropertyMetadata(false));
        
 public bool FocusArticlesOnStart
 {
  get => (bool)GetValue(FocusArticlesOnStartProperty);
  set => SetValue(FocusArticlesOnStartProperty, value);
 }

In XAML:

     <UserControl.Style>
         <Style TargetType="{x:Type local:MyControl}">
             <Setter Property="FocusArticlesOnStart">
                 <Setter.Value>
                     <MultiBinding Converter="{g:ToBoolean}" ConverterParameter="p0|!p1">
                         <MultiBinding.Bindings>
                             <Binding Path="FocusOnStart" />
                             <Binding Path="HasOrderString" />
                         </MultiBinding.Bindings>
                     </MultiBinding>
                 </Setter.Value>
             </Setter>
         </Style>
     </UserControl.Style>

Then I try to use this property in a method, invoked by Loaded event in code behind:

 private void UserControl_Loaded(object sender, RoutedEventArgs e)
 {
     if (FocusArticlesOnStart)
     {
         articleComboBox.Focus();
     }
     else
     {
         orderStringTextBox.Focus();
     }
 }

However, on the moment of Loaded the property is false. Though FocusOnStart and HasOrderString are set (as well as corresponding OnPropertyChange's invoked) before creation of this control, converter's MultiConvert method is only invoked after this method. According to documentation here,

Standard data binding (binding to local sources, such as other properties or directly defined data sources) will have occurred prior to Loaded.

Why doesn't it apply to my case? Where (in which method or after which event) should I be able to obtain correct FocusArticlesOnStart in order to set initial focus, when control is created?









windows-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

DaisyTian-1203 avatar image
0 Votes"
DaisyTian-1203 answered

I created a sample based on my understanding of your question to set the TextBox initial focus, if I misunderstand, please point out.
I make the ChargeCreate as UserControl and it XAML code is:

   <UserControl.Resources>
         <local:MyConverter x:Key="MyCon"></local:MyConverter>
         <Style TargetType="{x:Type local:ChargeCreate}">
             <Setter Property="local:ChargeCreate.FocusArticlesOnStart">
                 <Setter.Value>
                     <MultiBinding Converter="{StaticResource MyCon}" ConverterParameter="p1">
                         <MultiBinding.Bindings>
                             <Binding Path="FocusOnStart" />
                             <Binding Path="HasOrderString" />
                         </MultiBinding.Bindings>
                     </MultiBinding>
                 </Setter.Value>
             </Setter>
         </Style>
     </UserControl.Resources>
     <StackPanel>
         <ComboBox Name="articleComboBox" Width="120" Height="40"  ></ComboBox>
         <TextBox Name="orderStringTextBox" Width="120" Height="40"></TextBox>
     </StackPanel>

ChargeCreate.xaml.cs code is:(I set the Width set to 200 just to make it more obvious to see.)

 public partial class ChargeCreate : UserControl
     {
    
         public static readonly DependencyProperty FocusArticlesOnStartProperty = DependencyProperty.Register("FocusArticlesOnStart",
             typeof(bool), typeof(ChargeCreate), new PropertyMetadata(false));
    
         public bool FocusArticlesOnStart
         {
             get => (bool)GetValue(FocusArticlesOnStartProperty);
             set => SetValue(FocusArticlesOnStartProperty, value);
         }
    
         public ChargeCreate()
         {
             InitializeComponent();
         }
    
         private void UserControl_Loaded(object sender, RoutedEventArgs e)
         {
             if (FocusArticlesOnStart)
             {
                 articleComboBox.Focus();
                 articleComboBox.Width =200;
             }
             else
             {
                 orderStringTextBox.Focus();
                 orderStringTextBox.Width = 200;
             }
         }
     }

MyConverter code is:

   public class MyConverter : IMultiValueConverter
     {
         public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
         {
             bool obj;
    
             switch ((string)parameter)
             {
                 case "p0":
                     obj =  (bool)values[0];
                     break;
                 case "p1":
                 default:
                     obj =  (bool)values[1];
                     break;
             }
    
             return obj;
         }
    
         public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
         {
             string[] splitValues = ((string)value).Split(' ');
             return splitValues;
         }
     }

To use it in MainWindow:

 <Window.DataContext>
         <local:ViewModel></local:ViewModel>
     </Window.DataContext>
     <Grid>
         <local:ChargeCreate x:Name="uc" ></local:ChargeCreate>
     </Grid>

The ViewModel code is:

  public class ViewModel
     {
         public bool FocusOnStart { get; set; }
         public bool HasOrderString { get; set; }
    
         public ViewModel()
         {
             FocusOnStart = true;
             HasOrderString = false;
         }
     }

The result picture is:
96207-3.gif


If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


3.gif (114.0 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.