How to create a Close button in a User Control

14 posts, 1 answers
  1. herb
    herb avatar
    23 posts
    Member since:
    Oct 2018

    Posted 07 Dec 2019 Link to this post

    Have a User Control that is called when a button "about" is pressed.

    The UC works. Want to add a "Close" button that will close the window so it won't get orphaned later.

    I could use the "IsVisible = Visibility.Collapsed;" which works but it is not really gone. The UC has to RadListboxes which collects different data in each box. When I use the "IsVisible = Visibility.Collapsed;" the box disappears. When click on the "About" button it reappears with previous data. I prefer to make it truly close/destroyed.

    Is this possible and if so how? please.

    What code do you need the XAML or the .CS?

  2. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2322 posts

    Posted 11 Dec 2019 Link to this post

    Hello Herb,

    If you want to remove a control (like RadListBox for example) from the view entirely, you can remove it from the parent element that hosts it. For example, if the RadListBox is hosted in a Grid panel, you can cremove the control from its Children collection.

    myGrid.Children.Remove(myListBoxInstance);

    Regards,
    Martin Ivanov
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  3. herb
    herb avatar
    23 posts
    Member since:
    Oct 2018

    Posted 11 Dec 2019 Link to this post

    I should have posted some code from my project for clarity. Project is MVVM formatted. The "OnCloseCommand()" in the AboutViewModel.cs is where I want the user control window to be closed.

    From the MainWindow.xaml:

    <telerik:RadButton x:Name="btnAbout"
                       Margin="2,0,0.5,1.5"
                       Command="{Binding AboutButtonCommand}"
                       Visibility="Visible">
        <StackPanel Orientation="Horizontal">
            <TextBlock x:Name="btnImgAbout"
                       Margin="5,0,0,0"
                       FontSize="25"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       Text=""
                       Foreground="#FFD294EA"
                       FontFamily="/VoicemailAnalyticsWpf;component/Resources/#Segoe MDL2 Assets" />
            <TextBlock Margin="5,0,0,0"
                       FontSize="16"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"><Run Text="About" /></TextBlock>
        </StackPanel>
    </telerik:RadButton>

    From the AboutViewModel:

    using System.Collections.Generic;
    using System.Linq;
    using System.Diagnostics;
    using System.IO;
    using System.Collections.ObjectModel;
    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.CommandWpf;
    using System.Windows;
     
    namespace Wpsi.VmaUtilities.ViewModels
    {
        public class AboutViewModel : ViewModelBase
        {
            //build code to collect data into a list box.
            //Filename/tVersion
            /// <summary>GetProgramData()
            /// Find the path of the application.
            /// Count the number of files.
            /// Populate the array list to pass to the GetVersion.
            /// </summary>
             
     
            //private string _VersionList;
            private ObservableCollection<string> _versionList;
            private Visibility _isVisible = Visibility.Collapsed;
     
            #region RelayCommands
            public RelayCommand RefreshListCommand
            {
                get;
                set;
            }
     
            public RelayCommand CloseCommand
            {
                get;
                set;
            }
            #endregion RelayCommands
     
            #region Properties
            string sFile
            {
                get; set;
            }
            public ObservableCollection<string> VersionList
            {
                get => _versionList;
                set
                {
                    if (_versionList == value)
                    {
                        return;
                    }
                    _versionList = value;
                    RaisePropertyChanged(nameof(VersionList));//This name must match the name in the "ItemsSource="{Binding MrsUserDataTable}" of MrsUserSettings.xaml
                    //for this to work.
                }
            }
     
            public Visibility IsVisible
            {
                get => _isVisible;
                set
                {
                    _isVisible = value;
                    RaisePropertyChanged(nameof(IsVisible));
                }
            }
            #endregion Properties
     
     
            public AboutViewModel()
            {
                RefreshListCommand = new RelayCommand(OnRefreshListCommandExecute, () => true);
                CloseCommand = new RelayCommand(OnCloseCommand, () => true);
            }
     
            private List<string> GetProgramData()
            {
                DirectoryInfo fSet = new DirectoryInfo(System.AppDomain.CurrentDomain.BaseDirectory);
                string ProgramPath = Path.GetDirectoryName(fSet.ToString());
     
                //get list of dlls and exe for display
                FileInfo[] saFiles = fSet.GetFiles();
                string[] aFiles = new string[saFiles.Count()];
                int i = 0;
                 
                foreach (FileInfo f in saFiles)
                {
                    aFiles[i] = ProgramPath + "\\" + f.Name;
                    i++;
                }
                return GetVersion(aFiles);
            }
            /// <summary>GetVersion(string[] aFiles)
            /// Receive the array list of files found in the application path to reach "dll" and "exe"
            /// version details to put into the user control's RadListbox.
            /// Using Telerik's list box to show the file list.
            /// </summary>
            /// <param name="aFiles">
            /// An array of the files found in the program path
            /// </param>
            /// <returns>
            /// List<string> lsVersionList to the RadListbox control
            /// </returns>
            private List<string> GetVersion(string[] aFiles)
            {
                List<string> lsVersionList = new List<string>();
                FileVersionInfo vmaFileVersion = null;
     
                foreach (string sService in aFiles)
                {
                    if (sService.IndexOf(".exe") > 0)
                    {
                        vmaFileVersion = FileVersionInfo.GetVersionInfo(sService);
                        lsVersionList.Add(Path.GetFileName(vmaFileVersion.FileName) + "\t" + vmaFileVersion.FileVersion);
                    }
                    if (sService.IndexOf(".dll") > 0)
                    {
                        vmaFileVersion = FileVersionInfo.GetVersionInfo(sService);
                        lsVersionList.Add(Path.GetFileName(vmaFileVersion.FileName) + "\t" + vmaFileVersion.FileVersion);
                    }
                }
     
                return lsVersionList;
            }
     
            public void OnRefreshListCommandExecute()
            {
                VersionList = new ObservableCollection<string>(GetProgramData());
            }
            public void OnCloseCommand()
            {
                //Now Close the control
                IsVisible = Visibility.Collapsed;
                 
            }
     
            //private List<string> GetXpres()
            //{
            //  return;
            //}
     
            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        }//class AboutViewModel
    }//namespace Wpsi.VmaUtilities.ViewModels
  4. herb
    herb avatar
    23 posts
    Member since:
    Oct 2018

    Posted 12 Dec 2019 Link to this post

    I want to remove the UC window box that is called when the "about" button is clicked. I can make the "about" dialog box become invisible but I prefer to close it so if the program crashes it will not be left behind.
  5. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2322 posts

    Posted 16 Dec 2019 Link to this post

    Hello Herb,

    Thank you for the additional information.

    To achieve your requirement, you can use an approach with an attached property. For example, you can define a property called IsClosed which can be bound to the IsVisible of the AboutViewModel class. In the property changed callback of the attached, you can call the Close() method of the dialog window. I've attached a small example showing this approach. I hope this helps.

    Regards,
    Martin Ivanov
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  6. herb
    herb avatar
    23 posts
    Member since:
    Oct 2018

    Posted 16 Dec 2019 in reply to Martin Ivanov Link to this post

    Hello Martin, thank you for your sample.

    Not able to step through it because the "About" button is no seen and not calling the About window.

  7. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2322 posts

    Posted 17 Dec 2019 Link to this post

    Hello Herb,

    The project is using Xaml dlls. Can you please double check if it reference those? If the dlls are NoXaml, nothing will be shown. You can check the Missing Controls in the UI article for more information on this topic.

    Regards,
    Martin Ivanov
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  8. herb
    herb avatar
    23 posts
    Member since:
    Oct 2018

    Posted 21 Dec 2019 in reply to Martin Ivanov Link to this post

    Sorry for the long delay. Had to jump off this project.

    I reviewed you code/project. I see that you are closing an item.

    However I'm wishing to close a User Control Window I created to display my "About" RadListboxes.

    I know I can use the code below to hide the UCW buy still not clear on how to close the UCW instead of just hide it.

    There is no "X" in the control when you create a new window dialog. Closing the UCW in the UCW seems needing something I don't understand.

    public void OnCloseCommand()
    {
        //Now Close the control
        IsVisible = Visibility.Collapsed;
         
    }

  9. Dinko
    Admin
    Dinko avatar
    1037 posts

    Posted 25 Dec 2019 Link to this post

    Hi Herb,

    My name is Dinko, and I'm stepping into the conversation for my colleague Martin, who is currently out of the office.

    Reading your last post, I am not sure that I was able to understand your approach fully. I have taken a look at the project provided by Martin, and a Window element is closed when the button inside is pressed. 

    Is it possible to modify the project send from Martin to mimics your implementation and send it back to us? This way, we can have a better look and provide you with a suitable solution.

    Regards,
    Dinko
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  10. herb
    herb avatar
    23 posts
    Member since:
    Oct 2018

    Posted 25 Dec 2019 in reply to Dinko Link to this post

    I will do. I will get back as soon as I can. 
  11. herb
    herb avatar
    23 posts
    Member since:
    Oct 2018

    Posted 28 Dec 2019 in reply to herb Link to this post

    Ok here is a sample of what I have.

    When you click on the "About" button a user control "About.xaml" is called and creates the version list Radlistbox.

    There are three buttons "Close", "Save to File" and "Refresh".

    When the "Refresh" is click it will collect the version details in the application file.

    The button I'm interesting (now this could be my ignorance as what should happen) when press all the button does is make the user control About.xaml invisible. In my WinForms experience on some exceptions a form can be orphaned. I want to "close" "destroy" the user control.

    Is this possible from within the user control?

  12. herb
    herb avatar
    23 posts
    Member since:
    Oct 2018

    Posted 28 Dec 2019 in reply to herb Link to this post

    oops. here you go.

    Can't add "zip" so rename ".jpg" to "zip"

  13. Answer
    Martin Ivanov
    Admin
    Martin Ivanov avatar
    2322 posts

    Posted 30 Dec 2019 Link to this post

    Hello Herb,

    To achieve your requirement you will need to use a slightly different approach than setting the Visibility property of the About UserControl. The Visibility is useful if you need to have the control presented all of the time (hidden or not). However, to create and remove the UserControl from memory, you will need to remove it from its parent host (the Grid panel in your case). There is no straightforward approach that can be applied with the current setup, but you should be able to achieve your requirement by replacing the visibility approach with the other one (removing the child from the host).

    I've attached a project showing a possible approach to implement this.

    Another approach is to keep using the visibility and just make sure that everything in the view model is clean up when the control is hidden.

    Regards,
    Martin Ivanov
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  14. herb
    herb avatar
    23 posts
    Member since:
    Oct 2018

    Posted 30 Dec 2019 in reply to Martin Ivanov Link to this post

    Thank you Martin.

    I will review you sample code and if I have further question update you.

Back to Top