MaterialDesignInXAML / MaterialDesignInXamlToolkit

Google's Material Design in XAML & WPF, for C# & VB.Net.
http://materialdesigninxaml.net
MIT License
15.17k stars 3.43k forks source link

Hint does not being repositioned to the top left corner if the textbox has preconfigured text #3636

Closed bardur1234 closed 1 month ago

bardur1234 commented 3 months ago

Bug explanation

I upgraded recently to the latest version of Material Design and found out that hints in outlined textboxes are not moving up left side when the text is prepopulated (with Binding), when the presentation is showing. It works if there is no text and I am entering it.

I upgraded Material Design from version 4.9 to 5.1 and started experiencing the issue.

image

Version

5.1

nicolaihenriksen commented 3 months ago

@bardur1234 I am unable to reproduce this issue (on the latest code at least). Can you share a bit of XAML so I can see if anything there could be causing this behavior.

With this XAML:

<TextBox Style="{StaticResource MaterialDesignOutlinedTextBox}"
         materialDesign:HintAssist.Hint="My hint"
         Text="{Binding TextFromViewModel}" />

I get this result. image

I have tried: 1) setting a default value for ViewModel.TextFromViewModel, 2) setting a value set in the constructor, and 3) setting a value set after the Loaded event has fired in the UI. They all work as expected.

bardur1234 commented 3 months ago

Hello Nicolai,

Thank you for your quick response.

In my case, I created a User Control TextBoxWithUndoButton, which is being used in many other User Controls. The "hint" text is set in those User Controls. The "text" value of the text box is also being delivered from the User Controls. I am attaching one of the User Controls that include the Text Box.

Hope you will be able to reproduce the issue with my files.

I downgraded to version 5.0 from 5.1 to check if the issue exists in that version and can confirm that with version 5.0 I didn't experience that issue.

Regards, Vladislav


From: Nicolai Henriksen @.> Sent: July 20, 2024 2:42 AM To: MaterialDesignInXAML/MaterialDesignInXamlToolkit @.> Cc: bardur1234 @.>; Mention @.> Subject: Re: [MaterialDesignInXAML/MaterialDesignInXamlToolkit] Hint does not being repositioned to the top left corner if the textbox has preconfigured text (Issue #3636)

@bardur1234https://github.com/bardur1234 I am unable to reproduce this issue (on the latest code at least). Can you share a bit of XAML so I can see if anything there could be causing this behavior.

With this XAML:

<TextBox Style="{StaticResource MaterialDesignOutlinedTextBox}" materialDesign:HintAssist.Hint="My hint" Text="{Binding TextFromViewModel}" />

I get this result. image.png (view on web)https://github.com/user-attachments/assets/6231870c-c288-49a9-ac89-337d6fa24fdb

I have tried: 1) setting a default value for ViewModel.TextFromViewModel having a default value, 2) setting a value set in the constructor, and 3) setting a value set after the Loaded event has fired in the UI. They all work as expected.

— Reply to this email directly, view it on GitHubhttps://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/issues/3636#issuecomment-2240961552, or unsubscribehttps://github.com/notifications/unsubscribe-auth/BJ7Q65RTAP7CEURFAAB3OXTZNIBEHAVCNFSM6AAAAABLFSO6MSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENBQHE3DCNJVGI. You are receiving this because you were mentioned.Message ID: @.***>

using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input;

namespace Webex_Assistant.controls { ///

/// Interaction logic for TextBoxWithUndoButton.xaml /// public partial class TextBoxWithUndoButton : UserControl { public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(TextBoxWithUndoButton), new PropertyMetadata(""));

    public string TextBoxHint
    {
        get { return (string)GetValue(TextBoxHintProperty); }
        set { SetValue(TextBoxHintProperty, value); }
    }

    public static readonly DependencyProperty TextBoxHintProperty =
        DependencyProperty.Register("TextBoxHint", typeof(string), typeof(TextBoxWithUndoButton), new PropertyMetadata(""));

    public int MaxLength
    {
        get { return (int)GetValue(MaxLengthProperty); }
        set { SetValue(MaxLengthProperty, value); }
    }
    public static readonly DependencyProperty MaxLengthProperty =
        DependencyProperty.Register("MaxLength", typeof(int), typeof(TextBoxWithUndoButton));

    public string OriginalValue
    {
        get { return (string)GetValue(OriginalValueProperty); }
        set { SetValue(OriginalValueProperty, value); }
    }
    public static readonly DependencyProperty OriginalValueProperty =
        DependencyProperty.Register("OriginalValue", typeof(string), typeof(TextBoxWithUndoButton), new PropertyMetadata(""));

    public Visibility AsteriskVisibility
    {
        get { return (Visibility)GetValue(AsteriskVisibilityProperty); }
        set { SetValue(AsteriskVisibilityProperty, value); }
    }
    public static readonly DependencyProperty AsteriskVisibilityProperty =
        DependencyProperty.Register("AsteriskVisibility", typeof(Visibility), typeof(TextBoxWithUndoButton), new FrameworkPropertyMetadata(Visibility.Hidden));

    protected override void OnInitialized(EventArgs e)
    {
        InitializeComponent();
        base.OnInitialized(e);
    }

    private void txtboxValue_KeyUp(object sender, KeyEventArgs e)
    {
        iconAsterisk.Visibility = Visibility.Hidden;
        if (btnUndo != null)
        {
            if (((TextBox)sender).Text != OriginalValue)
            {
                btnUndo.IsEnabled = true;
                ((TextBox)sender).SetValue(TextBox.BackgroundProperty, System.Windows.Media.Brushes.AntiqueWhite);

            }
            else
            {
                btnUndo.IsEnabled = false;
                ((TextBox)sender).SetValue(TextBox.BackgroundProperty, System.Windows.Media.Brushes.Transparent);
            }
        }

    }
    private void Undo_Click(object sender, RoutedEventArgs e)
    {
        txtboxValue.Text= OriginalValue;
        txtboxValue.SetValue(TextBox.BackgroundProperty, System.Windows.Media.Brushes.Transparent);
        txtboxValue.GetBindingExpression(TextBox.TextProperty).UpdateSource();
        btnUndo.IsEnabled = false;
    }

}

}

using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using Webex_Assistant.controls; using Newtonsoft.Json; using System.IO; using System.Windows.Input; using System.Windows.Data; using System.Threading.Tasks; using static Webex_Assistant.NumberClass; using static Webex_Assistant.LocationClass; using static Webex_Assistant.ErrorExceptionMessageClass; using System.Threading; using System.Text.RegularExpressions; using System.Reflection; using System.Diagnostics;

namespace Webex_Assistant.forms { ///

/// Interaction logic for SingleLocationForm.xaml /// public partial class SingleLocationForm : UserControl { public event RoutedEventHandler Close; public event RoutedEventHandler CloseAndRefresh; public event RoutedEventHandler Refresh; public string Bearer { get { return (string)GetValue(BearerSourceProperty); } set { SetValue(BearerSourceProperty, value); } } public static readonly DependencyProperty BearerSourceProperty = DependencyProperty.Register("Bearer", typeof(string), typeof(SingleLocationForm)); public string ClientOrgID { get { return (string)GetValue(ClientOrgIDSourceProperty); } set { SetValue(ClientOrgIDSourceProperty, value); } } public static readonly DependencyProperty ClientOrgIDSourceProperty = DependencyProperty.Register("ClientOrgID", typeof(string), typeof(SingleLocationForm)); public string LocationID { get { return (string)GetValue(LocationIDSourceProperty); } set { SetValue(LocationIDSourceProperty, value); } } public static readonly DependencyProperty LocationIDSourceProperty = DependencyProperty.Register("LocationID", typeof(string), typeof(SingleLocationForm));

    private static CancellationTokenSource cancellationTokenSource;
    private static readonly string className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name;

    private LocationClass.Location location = null;
    private LocationWebexCallingDetails locationWebexCallingDetails = null;
    private PhoneNumberList phoneNumberList = null;
    private ScheduleList scheduleList = null;
    private CallingPermissionList callingPermissionList = null;
    private AccessCodeList accessCodeList = null;
    private AccessCodeList newAccessCodeList = new AccessCodeList();
    private VoicePortal voicePortal = null;

    private List<string> outsideDialDigitList = new List<string> { "None", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

    private JSONDeserializeAssistant.CountryList countryList = new JSONDeserializeAssistant.CountryList();

    protected override async void OnInitialized(EventArgs e)
    {
        InitializeComponent();
        base.OnInitialized(e);
        countryList = JsonConvert.DeserializeObject<JSONDeserializeAssistant.CountryList>(File.ReadAllText("../../../JSON/CountrysInformationJSON.json"));
        ucProgressControl.StopProcess += StopProcess;
        cancellationTokenSource = new CancellationTokenSource();
        if (LocationID != null) //If this is not a new location, the following methods and proceedures will be executed
        {
            try
            {
                ucProgressControl.Start(this);
                //Try to retrieve Location Webex Calling settings.
                locationWebexCallingDetails = new LocationWebexCallingDetails();
                locationWebexCallingDetails = await GetLocationWebexCallingDetails(Bearer, ClientOrgID, LocationID, cancellationTokenSource.Token);
                //If the location has Calling settings, relevant fields will become visibile. If not, Enable Webex Calling button will show up
                if (locationWebexCallingDetails != null)
                {
                    await LoadLocationAllDetails();
                    if (cancellationTokenSource.IsCancellationRequested) 
                    {
                        Close(this, null);
                        return; 
                    }
                    await Task.WhenAll(LoadLocationInfo(), LoadLocationWebexCallingDetails(), LoadLocationSchedule(), LoadOutgoingPermissions(), LoadVoicePortalDetails(), LoadAuthorizationCodes());
                    expanderLocationCallingDetails.Visibility = Visibility.Visible;
                    expanderScheduling.Visibility = Visibility.Visible;
                    expanderOutgoingCallPermissions.Visibility = Visibility.Visible;
                    expanderOutgoingPermissionLocationAccessCode.Visibility = Visibility.Visible;
                    expanderVoicePortal.Visibility = Visibility.Visible;
                }
                else
                {
                    await LoadLocationInfo();
                    stkPanelEnableWebexCalling.Visibility = Visibility.Visible;
                }
                ucProgressControl.Stop(this);
            }
            finally { cancellationTokenSource.Dispose(); }
        }
        else //If this is a new location, the following methods and proceedures will be executed
        {
            cmboxLocationCountry.ItemsSource = countryList.countries;
            cmboxLocationCountry.DisplayMemberPath = "name";
            cmboxLocationCountry.SelectedValuePath = "code";
            cmboxLocationCountry.SelectionChanged += new SelectionChangedEventHandler(LoadStatesTimeZonesEmailLanguage);
            JSONDeserializeAssistant.EmailLocaleListCollection emailLocaleListCollection = JsonConvert.DeserializeObject<JSONDeserializeAssistant.EmailLocaleListCollection>(File.ReadAllText("../../../JSON/PreferredLanguagesJSON.json"));
            cmboxLocationPreferredLanguage.ItemsSource = emailLocaleListCollection.emailLocaleList;
            cmboxLocationPreferredLanguage.DisplayMemberPath = "description";
            cmboxLocationPreferredLanguage.SelectedValuePath = "locale";
        }
    }
    //StopProcess is an event registered with ProgressControl. By clicking the Red X during the Progress is spinning, the process that is currenly running will be terminated
    private void StopProcess(object sender, RoutedEventArgs e)
    {
        // "cancellationTokenSource" is used to communicate with the called method and stop the process. https://www.youtube.com/watch?v=ZTKGRJy5P2M&ab_channel=IAmTimCorey
        cancellationTokenSource.Cancel();
        ucProgressControl.Stop(this); //Stop the spinning progress bar
        Debug.WriteLine($"{className}.StopProcess Information: The task has been canceled");
        MessageBox.Show("The task has been canceled");
    }

    private async Task LoadLocationAllDetails()
    {
        cancellationTokenSource = new CancellationTokenSource();
        Progress<string> progressTaskGetPhoneNumberList = new Progress<string>();
        //progressTaskGetPhoneNumberList.ProgressChanged += (o,e)=> { ucProgressControl.MessageTwoUpdate("Loaded phone numbers " + e);};
        Progress<string> progressTaskGetPhoneNumberListBasedLocationID = new Progress<string>();
        //progressTaskGetPhoneNumberList.ProgressChanged += (o,e)=> { ucProgressControl.MessageTwoUpdate("Loaded phone numbers " + e);};
        Task<LocationClass.Location> taskGetLocationDetails = GetLocationDetails(Bearer, ClientOrgID, LocationID, cancellationTokenSource.Token);
        Task<LocationWebexCallingDetails> taskGetLocationWebexCallingDetails = GetLocationWebexCallingDetails(Bearer, ClientOrgID, LocationID, cancellationTokenSource.Token);
        Task<PhoneNumberList> taskGetPhoneNumberListBasedLocationID = GetPhoneNumberListBasedLocationID(Bearer, ClientOrgID, LocationID, 2000, progressTaskGetPhoneNumberList, cancellationTokenSource.Token);
        Task<ScheduleList> taskReadListOfSchedules = ReadListOfSchedules(Bearer, ClientOrgID, LocationID, 2000, cancellationTokenSource.Token);
        Task<CallingPermissionList> taskGetLocationOutgoingPermission = GetLocationOutgoingPermission(Bearer, ClientOrgID, LocationID, cancellationTokenSource.Token);
        Task<AccessCodeList> taskGetOutgoingPermissionLocationAccessCode = GetOutgoingPermissionLocationAccessCode(Bearer,ClientOrgID, LocationID, cancellationTokenSource.Token);
        Task<VoicePortal> taskGetVoicePortal = GetVoicePortal(Bearer, ClientOrgID, LocationID, cancellationTokenSource.Token);

        await Task.WhenAll(taskGetLocationDetails, taskGetLocationWebexCallingDetails, taskGetPhoneNumberListBasedLocationID, taskReadListOfSchedules, taskGetLocationOutgoingPermission, taskGetVoicePortal, taskGetOutgoingPermissionLocationAccessCode);

        location = taskGetLocationDetails.Result;
        locationWebexCallingDetails = taskGetLocationWebexCallingDetails.Result;
        phoneNumberList = taskGetPhoneNumberListBasedLocationID.Result;
        scheduleList = taskReadListOfSchedules.Result;
        callingPermissionList = taskGetLocationOutgoingPermission.Result;
        accessCodeList = taskGetOutgoingPermissionLocationAccessCode.Result;
        voicePortal = taskGetVoicePortal.Result;
        if (location == null || locationWebexCallingDetails == null || phoneNumberList == null || scheduleList == null || callingPermissionList == null || voicePortal == null ) { return; }

    }

    private void LoadStatesTimeZonesEmailLanguage(object sender, RoutedEventArgs e)
    {
        List<JSONDeserializeAssistant.State> stateList = countryList.countries.Where(x => x.code == ((ComboBoxWithUndoButton)sender).SelectedValue).Select(x => x.states).FirstOrDefault();
        cmboxLocationState.ItemsSource = cmboxLocationTimeZone.ItemsSource = stateList;
        cmboxLocationState.DisplayMemberPath = "name";
        cmboxLocationState.SelectedValuePath = "code";
        cmboxLocationTimeZone.ItemsSource = countryList.countries.Where(x => x.code == ((ComboBoxWithUndoButton)sender).SelectedValue).Select(x => x.timeZones).FirstOrDefault();
    }

    private async Task LoadLocationInfo()
    {
        string methodName = Regex.Match(MethodBase.GetCurrentMethod().DeclaringType.Name, @"(?<=<)([^>]+)(?=>)").ToString();
        Debug.WriteLine($"{className}.{methodName} Information: LoadLocationInfo method start");
        ucProgressControl.MessageOneUpdate("Loading Location Details");

        if (location == null) { Debug.WriteLine($"{className}.{methodName} Error: Null was returned from RestRequest"); return; }
        lblLocationName.Content = location.name;
        lblLocationName.Visibility = Visibility.Visible;
        dockpanelLocationDetails.DataContext = location;
        cmboxLocationCountry.ItemsSource = countryList.countries;
        cmboxLocationCountry.DisplayMemberPath = "name";
        cmboxLocationCountry.SelectedValuePath = "code";
        cmboxLocationCountry.SelectedValue = cmboxLocationCountry.OriginalValue = location.address.country;
        if (cmboxLocationCountry.SelectedValue == null || countryList == null)
        {
            cmboxLocationCountry.SelectedValue = location?.address.country + "missing";
        }
        cmboxLocationCountry.IsEnabled = false;

        List<JSONDeserializeAssistant.State> stateList = countryList.countries.Where(x => x.code == location?.address.country).Select(x => x.states).FirstOrDefault();
        cmboxLocationState.ItemsSource = stateList;
        cmboxLocationState.DisplayMemberPath = "name";
        cmboxLocationState.SelectedValuePath = "code";
        cmboxLocationState.SelectedValue = cmboxLocationState.OriginalValue = location.address.state;
        if (cmboxLocationState.SelectedValue == null || stateList == null)
        {
            stateList.Add(new JSONDeserializeAssistant.State() { name = location?.address.state + " - missing", code = location?.address.state + "missing" });
            cmboxLocationState.SelectedValue = location?.address.state + "missing";
        }
        cmboxLocationTimeZone.ItemsSource = countryList.countries.Where(x => x.code == location?.address.country).Select(x => x.timeZones).FirstOrDefault();
        cmboxLocationTimeZone.SelectedValue = cmboxLocationTimeZone.OriginalValue = location.timeZone;
        if ((location.timeZone != null) && (cmboxLocationTimeZone.SelectedValue == null || stateList == null))
        {
            cmboxLocationTimeZone.SelectedValue = location?.timeZone + " - missing";
        }
        JSONDeserializeAssistant.EmailLocaleListCollection emailLocaleListCollection = JsonConvert.DeserializeObject<JSONDeserializeAssistant.EmailLocaleListCollection>(File.ReadAllText("../../../JSON/PreferredLanguagesJSON.json"));
        cmboxLocationPreferredLanguage.ItemsSource = emailLocaleListCollection.emailLocaleList;
        cmboxLocationPreferredLanguage.DisplayMemberPath = "description";
        cmboxLocationPreferredLanguage.SelectedValuePath = "locale";
        cmboxLocationPreferredLanguage.SelectedValue = cmboxLocationPreferredLanguage.OriginalValue = location?.preferredLanguage;
        if (cmboxLocationPreferredLanguage.SelectedValue == null)
        {
            emailLocaleListCollection.emailLocaleList.Add(new JSONDeserializeAssistant.EmailLocaleList { locale = location?.preferredLanguage + " - missing", description = location?.preferredLanguage + " - missing" });
            cmboxLocationPreferredLanguage.SelectedValue = location?.preferredLanguage + " - missing";
        }
    }
    private async Task LoadLocationWebexCallingDetails()
    {
        string methodName = Regex.Match(MethodBase.GetCurrentMethod().DeclaringType.Name, @"(?<=<)([^>]+)(?=>)").ToString();
        Debug.WriteLine($"{className}.{methodName} Information: LoadLocationWebexCallingDetails method start");

        dockpanelLocationCallingDetails.DataContext = locationWebexCallingDetails;
        cmboxMainNumber.ItemsSource = phoneNumberList.phoneNumbers.Where(x => x.phoneNumber != null);
        cmboxMainNumber.SelectedValue = cmboxMainNumber.OriginalValue = locationWebexCallingDetails.callingLineId.phoneNumber;

        //The following DataTemplate and FrameworkElements are to create a ComboBox with Phone Numbers and Users associated to these phone numbers 
        DataTemplate cmboxMainNumberDataTemplate = new DataTemplate(); //Create a DataTemplate
        FrameworkElementFactory stackPanel = new FrameworkElementFactory(typeof(StackPanel)); //Create a StackPanel
        stackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
        FrameworkElementFactory textBlockPhoneNumber = new FrameworkElementFactory(typeof(TextBlock)); //Create a PhoneNumber TextBlock 
        textBlockPhoneNumber.SetBinding(TextBlock.TextProperty, new Binding("phoneNumber"));
        stackPanel.AppendChild(textBlockPhoneNumber);
        FrameworkElementFactory textBlockFirstName = new FrameworkElementFactory(typeof(TextBlock)); //Create a FirstName TextBlock
        textBlockFirstName.SetBinding(TextBlock.TextProperty, new Binding("owner.firstName"));
        textBlockFirstName.SetValue(TextBlock.MarginProperty, new Thickness(10, 0, 2, 0));
        stackPanel.AppendChild(textBlockFirstName);
        FrameworkElementFactory textBlockLastName = new FrameworkElementFactory(typeof(TextBlock)); //Create a LastName TextBlock
        textBlockLastName.SetBinding(TextBlock.TextProperty, new Binding("owner.lastName"));
        textBlockLastName.SetValue(TextBlock.MarginProperty, new Thickness(2, 0, 2, 0));
        stackPanel.AppendChild(textBlockLastName);
        cmboxMainNumberDataTemplate.VisualTree = stackPanel; //Create a DataTemplate VisualTree
        cmboxMainNumber.ItemTemplate = cmboxMainNumberDataTemplate; //Associate the DataTemplate to ComboBox
        JSONDeserializeAssistant.LanguageList annauncementLanguageList = JsonConvert.DeserializeObject<JSONDeserializeAssistant.LanguageList>(File.ReadAllText("../../../JSON/AnnouncementLanguagesJSON.json"));
        cmboxAnnouncementLanguage.ItemsSource = annauncementLanguageList.languages;
        cmboxAnnouncementLanguage.DisplayMemberPath = "name";
        cmboxAnnouncementLanguage.SelectedValuePath = "code";
        cmboxAnnouncementLanguage.SelectedValue = cmboxAnnouncementLanguage.OriginalValue = locationWebexCallingDetails.announcementLanguage;
        if (cmboxAnnouncementLanguage.SelectedValue == null)
        {
            annauncementLanguageList.languages.Add(new JSONDeserializeAssistant.Language { code = locationWebexCallingDetails.announcementLanguage + " - missing", name = locationWebexCallingDetails.announcementLanguage + " - missing" });
            cmboxLocationPreferredLanguage.SelectedValue = locationWebexCallingDetails.announcementLanguage + " - missing";
        }
        cmboxOutsideDialDigit.ItemsSource = outsideDialDigitList;
        cmboxOutsideDialDigit.SelectedValue = cmboxOutsideDialDigit.OriginalValue = locationWebexCallingDetails.outsideDialDigit;
    }
    private async Task LoadLocationSchedule()
    {

        dtgridLocationSchedule.ItemsSource = scheduleList.schedules;
        dtgridLocationSchedule.IsReadOnly = true;
    }

    private async Task LoadOutgoingPermissions()
    {
        List<string> actionList = new List<string> { "ALLOW", "BLOCK", "AUTH_CODE", "TRANSFER_NUMBER_1", "TRANSFER_NUMBER_2", "TRANSFER_NUMBER_3" };
        cmboxInternalCalls.ItemsSource = actionList;
        cmboxInternalCalls.SelectedValue = cmboxInternalCalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("INTERNAL_CALL")).Select(x => x.action).First();
        cmboxInternalCalls.IsChecked = cmboxInternalCalls.ToggleButtonOriginalStatus = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("INTERNAL_CALL")).Select(x => x.transferEnabled).First();
        cmboxTollFreeCalls.ItemsSource = actionList;
        cmboxTollFreeCalls.SelectedValue = cmboxTollFreeCalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("TOLL_FREE")).Select(x => x.action).First();
        cmboxTollFreeCalls.IsChecked = cmboxTollFreeCalls.ToggleButtonOriginalStatus = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("TOLL_FREE")).Select(x => x.transferEnabled).First();
        cmboxNationalCalls.ItemsSource = actionList;
        cmboxNationalCalls.SelectedValue = cmboxNationalCalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("NATIONAL")).Select(x => x.action).First();
        cmboxNationalCalls.IsChecked = cmboxNationalCalls.ToggleButtonOriginalStatus = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("NATIONAL")).Select(x => x.transferEnabled).First();
        cmboxInternationalCalls.ItemsSource = actionList;
        cmboxInternationalCalls.SelectedValue = cmboxInternationalCalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("INTERNATIONAL")).Select(x => x.action).First();
        cmboxInternationalCalls.IsChecked = cmboxInternationalCalls.ToggleButtonOriginalStatus = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("INTERNATIONAL")).Select(x => x.transferEnabled).First();
        cmboxOperatorAssistanceCalls.ItemsSource = actionList;
        cmboxOperatorAssistanceCalls.SelectedValue = cmboxOperatorAssistanceCalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("OPERATOR_ASSISTED")).Select(x => x.action).First();
        cmboxOperatorAssistanceCalls.IsChecked = cmboxOperatorAssistanceCalls.ToggleButtonOriginalStatus = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("OPERATOR_ASSISTED")).Select(x => x.transferEnabled).First();
        cmboxDirectoryAssistanceCalls.ItemsSource = actionList;
        cmboxDirectoryAssistanceCalls.SelectedValue = cmboxDirectoryAssistanceCalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("CHARGEABLE_DIRECTORY_ASSISTED")).Select(x => x.action).First();
        cmboxDirectoryAssistanceCalls.IsChecked = cmboxDirectoryAssistanceCalls.ToggleButtonOriginalStatus = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("CHARGEABLE_DIRECTORY_ASSISTED")).Select(x => x.transferEnabled).First();
        cmboxServicesICalls.ItemsSource = actionList;
        cmboxServicesICalls.SelectedValue = cmboxServicesICalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("SPECIAL_SERVICES_I")).Select(x => x.action).First();
        cmboxServicesICalls.IsChecked = cmboxServicesICalls.ToggleButtonOriginalStatus = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("SPECIAL_SERVICES_I")).Select(x => x.transferEnabled).First();
        cmboxServicesIICalls.ItemsSource = actionList;
        cmboxServicesIICalls.SelectedValue = cmboxServicesIICalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("SPECIAL_SERVICES_II")).Select(x => x.action).First();
        cmboxServicesIICalls.IsChecked = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("SPECIAL_SERVICES_II")).Select(x => x.transferEnabled).First();
        cmboxPremiumServicesICalls.ItemsSource = actionList;
        cmboxPremiumServicesICalls.SelectedValue = cmboxPremiumServicesICalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("PREMIUM_SERVICES_I")).Select(x => x.action).First();
        cmboxPremiumServicesICalls.IsChecked = cmboxPremiumServicesICalls.ToggleButtonOriginalStatus = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("PREMIUM_SERVICES_I")).Select(x => x.transferEnabled).First();
        cmboxPremiumServicesIICalls.ItemsSource = actionList;
        cmboxPremiumServicesIICalls.SelectedValue = cmboxPremiumServicesIICalls.OriginalValue = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("PREMIUM_SERVICES_II")).Select(x => x.action).First();
        cmboxPremiumServicesIICalls.IsChecked = cmboxPremiumServicesIICalls.ToggleButtonOriginalStatus = callingPermissionList.callingPermissions.Where(x => x.callType.Equals("PREMIUM_SERVICES_II")).Select(x => x.transferEnabled).First();
    }

    private async Task LoadAuthorizationCodes()
    {
        dtgridOutgoingPermissionLocationAccessCode.ItemsSource = accessCodeList.accessCodes;
    }

    private async Task LoadVoicePortalDetails()
    {
            string methodName = Regex.Match(MethodBase.GetCurrentMethod().DeclaringType.Name, @"(?<=<)([^>]+)(?=>)").ToString();
            txtboxVoicePortalName.Text = txtboxVoicePortalName.OriginalValue = voicePortal.name;
            txtboxCallerIDFirstName.Text = txtboxCallerIDFirstName.OriginalValue = voicePortal.firstName;
            txtboxCallerIDLastName.Text = txtboxCallerIDLastName.OriginalValue = voicePortal.lastName;
            JSONDeserializeAssistant.LanguageList voicePortalLanguageList = JsonConvert.DeserializeObject<JSONDeserializeAssistant.LanguageList>(File.ReadAllText("../../../JSON/AnnouncementLanguagesJSON.json"));
            cmboxVoicePortalLanguage.ItemsSource = voicePortalLanguageList.languages;
            cmboxVoicePortalLanguage.DisplayMemberPath = "name";
            cmboxVoicePortalLanguage.SelectedValuePath = "code";
            cmboxVoicePortalLanguage.SelectedValue = cmboxVoicePortalLanguage.OriginalValue = voicePortal.languageCode;
            if (cmboxVoicePortalLanguage.SelectedValue == null)
            {
                voicePortalLanguageList.languages.Add(new JSONDeserializeAssistant.Language { code = voicePortal.languageCode + " - missing", name = voicePortal.languageCode + " - missing" });
                cmboxLocationPreferredLanguage.SelectedValue = voicePortal.languageCode + " - missing";
            }
            cmboxPhoneNumber.ItemsSource = phoneNumberList.phoneNumbers.Where(x => x.phoneNumber != null).Where(x => x.owner == null);
            cmboxPhoneNumber.SelectedValuePath = "phoneNumber";
            cmboxPhoneNumber.DisplayMemberPath = "phoneNumber";
            cmboxPhoneNumber.SelectedValue = cmboxPhoneNumber.OriginalValue = voicePortal.phoneNumber?.ToString();
            txtboxExtension.Text = txtboxExtension.OriginalValue = voicePortal.extension;
    }

    private async void btnEnableWebexCalling_Click(object sender, RoutedEventArgs e)
    {
        ucProgressControl.Start(this);
        cancellationTokenSource = new CancellationTokenSource();
        try
        {
            var response = await EnableLocationForWebexCalling(Bearer, ClientOrgID, LocationID, cancellationTokenSource.Token);
            if (response.StatusCode.ToString() != "Created" && !response.ErrorMessage.Contains("The operation was canceled.")) { MessageBox.Show(response.Content); }
            else if (response.StatusCode.ToString() == "Created") RefreshForm();
            else if (response.ErrorMessage.Contains("The operation was canceled.")) Close(this,null);
        }
        finally 
        { 
            cancellationTokenSource.Dispose();
        }
        ucProgressControl.Stop(this);
    }
    private async Task RefreshForm()
    {
        cancellationTokenSource = new CancellationTokenSource();
        stkPanelEnableWebexCalling.Visibility = Visibility.Collapsed;
        expanderLocationCallingDetails.Visibility = Visibility.Visible;
        expanderScheduling.Visibility = Visibility.Visible;
        expanderOutgoingCallPermissions.Visibility = Visibility.Visible;
        expanderVoicePortal.Visibility = Visibility.Visible;
        try
        {
            await Task.WhenAll(LoadLocationInfo(), LoadLocationWebexCallingDetails(), LoadLocationSchedule(), LoadOutgoingPermissions(), LoadVoicePortalDetails());
        }
        finally { cancellationTokenSource.Dispose(); }

    }

    private void btnCloseForm_Click(object sender, RoutedEventArgs e)
    {
        if (Close != null)
            Close(sender, e);
    }

    private async void btnSaveForm_Click(object sender, RoutedEventArgs e)
    {
        //SaveForm method validates if the form has any missing required values. It also will collect all the changes and forward it to SaveConfirmationDialog for final approval
        bool missingValueExist = false;
        IEnumerable<TextBoxWithUndoButton> dockpanelLocationDetailsTexBoxCollection = dockpanelLocationDetails.Children.OfType<TextBoxWithUndoButton>();
        IEnumerable<ComboBoxWithUndoButton> dockpanelLocationDetailsComboBoxCollection = dockpanelLocationDetails.Children.OfType<ComboBoxWithUndoButton>();

        IEnumerable<TextBoxWithUndoButton> dockpanelLocationCallingDetailsTextBoxCollection = dockpanelLocationCallingDetails.Children.OfType<TextBoxWithUndoButton>();
        IEnumerable<TextBoxWithErrorMessageUndoButton> dockpanelLocationCallingDetailsTextBoxWithErrorMessageCollection = dockpanelLocationCallingDetails.Children.OfType<TextBoxWithErrorMessageUndoButton>();
        IEnumerable<ComboBoxWithUndoButton> dockpanelLocationCallingDetailsComboBoxCollection = dockpanelLocationCallingDetails.Children.OfType<ComboBoxWithUndoButton>();

        IEnumerable<ComboBoxWithUndoAndToggleButton> dockpanelOutgoingCallPermissionsComboBoxWithUndoAndToggleButton = dockpanelOutgoingCallPermissions.Children.OfType<ComboBoxWithUndoAndToggleButton>();

        List<ChangeClass.Change> changeList = new List<ChangeClass.Change>();
        bool changesFoundInLocationDetails = false;
        bool changesFoundInLocationCallingDetails = false;
        bool changesFoundInOutgoingCallPermissions = false;

        foreach (TextBoxWithUndoButton textBoxWithUndoButton in dockpanelLocationDetailsTexBoxCollection)
        {
            if (textBoxWithUndoButton.Text == "")
            {
                if (textBoxWithUndoButton.TextBoxHint != "Address 2")
                {
                    missingValueExist = true;
                    textBoxWithUndoButton.AsteriskVisibility = Visibility.Visible;
                }
            }
            else if (textBoxWithUndoButton.Text != textBoxWithUndoButton.OriginalValue && textBoxWithUndoButton.Text != "")
            {
                changeList.Add(new ChangeClass.Change { id = textBoxWithUndoButton.TextBoxHint, origianlValue = textBoxWithUndoButton.OriginalValue, newValue = textBoxWithUndoButton.Text });
                changesFoundInLocationDetails = true;
            }
        }
        foreach (ComboBoxWithUndoButton comboBoxWithUndoButton in dockpanelLocationDetailsComboBoxCollection)
        {
            if (comboBoxWithUndoButton.SelectedValue == "" || comboBoxWithUndoButton.SelectedValue == null)
            {
                missingValueExist = true;
                comboBoxWithUndoButton.AsteriskVisibility = Visibility.Visible;
            }
            else if (comboBoxWithUndoButton.SelectedValue != comboBoxWithUndoButton.OriginalValue && comboBoxWithUndoButton.SelectedValue != "")
            {
                changeList.Add(new ChangeClass.Change { id = comboBoxWithUndoButton.ComboBoxHint, origianlValue = comboBoxWithUndoButton.OriginalValue, newValue = comboBoxWithUndoButton.SelectedValue });
                changesFoundInLocationDetails = true;
            }
        }
        foreach (TextBoxWithUndoButton textBoxWithUndoButton in dockpanelLocationCallingDetailsTextBoxCollection)
        {
            if (textBoxWithUndoButton.Text != textBoxWithUndoButton.OriginalValue)
            {
                changeList.Add(new ChangeClass.Change { id = textBoxWithUndoButton.TextBoxHint, origianlValue = textBoxWithUndoButton.OriginalValue, newValue = textBoxWithUndoButton.Text });
                changesFoundInLocationCallingDetails = true;
            }
        }
        foreach (TextBoxWithErrorMessageUndoButton textBoxWithErrorMessageUndoButton in dockpanelLocationCallingDetailsTextBoxWithErrorMessageCollection)
        {
            if (textBoxWithErrorMessageUndoButton.Text != textBoxWithErrorMessageUndoButton.OriginalValue)
            {
                changeList.Add(new ChangeClass.Change { id = textBoxWithErrorMessageUndoButton.TextBoxHint, origianlValue = textBoxWithErrorMessageUndoButton.OriginalValue, newValue = textBoxWithErrorMessageUndoButton.Text });
                changesFoundInLocationCallingDetails = true;
            }
        }
        foreach (ComboBoxWithUndoButton comboBoxWithUndoButton in dockpanelLocationCallingDetailsComboBoxCollection)
        {
            if (comboBoxWithUndoButton.SelectedValue != comboBoxWithUndoButton.OriginalValue && comboBoxWithUndoButton.SelectedValue != "")
            {
                changeList.Add(new ChangeClass.Change { id = comboBoxWithUndoButton.ComboBoxHint, origianlValue = comboBoxWithUndoButton.OriginalValue, newValue = comboBoxWithUndoButton.SelectedValue });
                changesFoundInLocationCallingDetails = true;
            }
        }

        List<ComboBoxWithUndoAndToggleButton> listToChangeOfOutgoingCallPermissions = new List<ComboBoxWithUndoAndToggleButton>();
        foreach (ComboBoxWithUndoAndToggleButton comboBoxWithUndoAndToggleButton in dockpanelOutgoingCallPermissionsComboBoxWithUndoAndToggleButton)
        {
            if (comboBoxWithUndoAndToggleButton.SelectedValue != comboBoxWithUndoAndToggleButton.OriginalValue && comboBoxWithUndoAndToggleButton.SelectedValue != "")
            {
                listToChangeOfOutgoingCallPermissions.Add(comboBoxWithUndoAndToggleButton);
                changeList.Add(new ChangeClass.Change { id = comboBoxWithUndoAndToggleButton.ComboBoxHint, origianlValue = comboBoxWithUndoAndToggleButton.OriginalValue, newValue = comboBoxWithUndoAndToggleButton.SelectedValue });
                changesFoundInOutgoingCallPermissions = true;
            }
        }

        if (missingValueExist)
        {
            MessageBox.Show("There are required values missing. Please complete them");
        }
        else
        {
            //Opens "Save Configuration Form" and presents all the changes that will be applied
            var saveConfirmationDialog = new SaveConfirmationDialog()
            {
                Owner = App.Current.MainWindow,
                ShowInTaskbar = false,
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
                WindowStyle = WindowStyle.None,
                AllowsTransparency = true,
                ChangeList = changeList,
            };

            if (saveConfirmationDialog.ShowDialog() == true)
            {
                cancellationTokenSource = new CancellationTokenSource();
                ucProgressControl.Start(this);
                try
                {
                    //If this is a new Location, the LocationID will be empty. A new Location will be created.
                    if (LocationID == null)
                    {
                        LocationClass.Location body = new LocationClass.Location();
                        body.name = txtboxLocationName.Text;
                        body.address.country = cmboxLocationCountry.SelectedValue;
                        body.address.address1 = txtboxLocationAddress1.Text;
                        body.address.address2 = txtboxLocationAddress2.Text;
                        body.address.city = txtboxLocationCity.Text;
                        body.address.state = cmboxLocationState.SelectedValue;
                        body.address.postalCode = txtboxLocationPostalCode.Text;
                        body.timeZone = cmboxLocationTimeZone.SelectedValue;
                        body.preferredLanguage = cmboxLocationPreferredLanguage.SelectedValue;
                        var response = await CreateLocation(Bearer, ClientOrgID, body, cancellationTokenSource.Token);
                        if (response.StatusCode.ToString() == "Created") CloseAndRefresh(sender, e);
                        else if (response.StatusCode != null) { MessageBox.Show(JsonConvert.DeserializeObject<ErrorCode>(response.Content).message); }
                    }
                    //Else, the location will be updated with the new parameters
                    else
                    {
                        if (changesFoundInLocationDetails)
                        {
                            LocationClass.Location body = new LocationClass.Location();
                            body.name = txtboxLocationName.Text;
                            body.address.country = cmboxLocationCountry.SelectedValue;
                            body.address.address1 = txtboxLocationAddress1.Text;
                            body.address.address2 = txtboxLocationAddress2.Text;
                            body.address.city = txtboxLocationCity.Text;
                            body.address.state = cmboxLocationState.SelectedValue;
                            body.address.postalCode = txtboxLocationPostalCode.Text;
                            body.timeZone = cmboxLocationTimeZone.SelectedValue;
                            body.preferredLanguage = cmboxLocationPreferredLanguage.SelectedValue;
                            await UpdateLocation(Bearer, ClientOrgID, LocationID, body, cancellationTokenSource.Token);
                        }
                        if (changesFoundInLocationCallingDetails)
                        {
                            LocationClass.LocationWebexCallingDetails body = new LocationClass.LocationWebexCallingDetails();
                            body.callingLineId.phoneNumber = cmboxMainNumber.SelectedValue;
                            body.announcementLanguage = cmboxAnnouncementLanguage.SelectedValue;
                            body.outsideDialDigit = cmboxOutsideDialDigit.SelectedValue == "None" ? null : cmboxOutsideDialDigit.SelectedValue;
                            body.routingPrefix = txtboxRoutingPrefix.Text == "" ? null : txtboxRoutingPrefix.Text;
                            await UpdateLocationWebexCallingDetails(Bearer, ClientOrgID, LocationID, body ,cancellationTokenSource.Token);
                        }
                        if (changesFoundInOutgoingCallPermissions)
                        {
                            CallingPermissionList body = new CallingPermissionList();
                            foreach (ComboBoxWithUndoAndToggleButton comboBoxWithUndoAndToggleButton in listToChangeOfOutgoingCallPermissions)
                            {
                                body.callingPermissions.Add(new CallingPermission() { callType = comboBoxWithUndoAndToggleButton.Uid, action = comboBoxWithUndoAndToggleButton.SelectedValue, transferEnabled = comboBoxWithUndoAndToggleButton.IsChecked });
                            }

                            /*
                             * 
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxInternalCalls" ComboBox
                             * <!--Toll-Free Calls Restriction-->
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxTollFreeCalls" ComboBox
                             * <!--National Calls Restriction-->
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxNationalCalls" ComboBox
                             * <!--International Calls Restriction-->
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxInternationalCalls" Com
                             * <!--Operator Assistance Calls Restriction-->
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxOperatorAssistanceCalls
                             * <!--Chargeable Directory Assistance Calls Restriction-->
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxDirectoryAssistanceCall
                             * <!--Special Services I Calls Restriction-->
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxServicesICalls" ComboBo
                             * <!--Special Services II Calls Restriction-->
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxServicesIICalls" ComboB
                             * <!--Premium Services I Calls Restriction-->
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxPremiumServicesICalls" 
                             * <!--Premium Services II Calls Restriction-->
                             * <usercontrols:ComboBoxWithUndoAndToggleButton x:Name="cmboxPremiumServicesIICalls"
                             * 
                             * 
                             * 
                             * 
                             * 
                             * 
                            */
                        }

                        ucProgressControl.Stop(this);
                        CloseAndRefresh(sender, e);
                    }
                }
                finally { cancellationTokenSource.Dispose(); }
            }
        }
    }

    private void btnDeleteAccessCode_Click(object sender, MouseButtonEventArgs e)
    {
        AccessCode accessCodeToBeRemoved = ((FrameworkElement)sender).DataContext as AccessCode;

        if (newAccessCodeList == null)
        {
            AccessCodeList newAccessCodeList = new AccessCodeList();
            newAccessCodeList.accessCodes.AddRange(accessCodeList.accessCodes);
        }

        newAccessCodeList.accessCodes.Remove(accessCodeToBeRemoved);
        dtgridOutgoingPermissionLocationAccessCode.ItemsSource = newAccessCodeList.accessCodes;
    }
}

}

nicolaihenriksen commented 3 months ago

I downgraded to version 5.0 from 5.1 to check if the issue exists in that version and can confirm that with version 5.0 I didn't experience that issue.

So, version 5.1 did include a major refactoring of the SmartHint, especially regarding the placement of the hint. That could explain why you see the difference. But unfortunately I am still not able to reproduce it in any way, shape, or form.

The code you have pasted in the response above is taken quite a bit out of context, and is difficult for me to decipher anything from (it does not compile without other needed bits). I am however noticing your use of async/await in many places. I'll try a few other things down that path to see if I can reproduce the issue.

Simply wrapping the TextBox in a UserControl exposing a DependencyProperty for both the text and hint works fine for me.

A couple of things I noticed in your code:

nicolaihenriksen commented 3 months ago

@bardur1234 You wouldn't happen to be setting HintAssist.FloatingOffset explicitly in your code would you? If so, the value set will take precedence and basically opt-out of the automatically calculated floating offset.

bardur1234 commented 3 months ago

Hello Nicolai,

No, I am not using HintAssist.FloatingOffset.

Regards, Vladislav


From: Nicolai Henriksen @.> Sent: July 20, 2024 2:44 PM To: MaterialDesignInXAML/MaterialDesignInXamlToolkit @.> Cc: bardur1234 @.>; Mention @.> Subject: Re: [MaterialDesignInXAML/MaterialDesignInXamlToolkit] Hint does not being repositioned to the top left corner if the textbox has preconfigured text (Issue #3636)

@bardur1234https://github.com/bardur1234 You wouldn't happen to be setting HintAssist.FloatingOffset explicitly in your code would you? If so, the value set will take precedence and basically opt-out of the automatically calculated floating offset.

— Reply to this email directly, view it on GitHubhttps://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/issues/3636#issuecomment-2241258575, or unsubscribehttps://github.com/notifications/unsubscribe-auth/BJ7Q65X4TTDKJRIYQ56VCXLZNKVXBAVCNFSM6AAAAABLFSO6MSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENBRGI2TQNJXGU. You are receiving this because you were mentioned.Message ID: @.***>

github-actions[bot] commented 2 months ago

This issue is marked stale because it has been open 30 days with no activity. Remove stale label or update the issue, otherwise it will be closed in 14 days.

nicolaihenriksen commented 2 months ago

@bardur1234 Would you be able to share some of your XAML, or possibly even a small demo repo with code that reproduces this? I am unable to reproduce it with the information given above.

github-actions[bot] commented 1 month ago

This issue is marked stale because it has been open 30 days with no activity. Remove stale label or update the issue, otherwise it will be closed in 14 days.

github-actions[bot] commented 1 month ago

This issue was closed because it has been stalled for 14 days with no activity.