Search code examples
c#wpfxamluser-controls

How to get the value from an enum custom property in custom usercontrol WPF,C#?


I'm creating a user control which is simple with 3 custom properties: two of them works fine but I have troubleshootings with the third which is an enum. My user control is a combobox which displays connections to databases (MySql, Sql server...) and I want to display either all, either MySql , either SqlServer etc connections thanks to the TypeOfDatabase property.

My problem is that my TypeOfDatabase property is equal to "all" in BaseConnection.xaml.cs switch thus I can't have only MySql connections.

I'm new in WPF and I don't know what I have to do to take the value set.

I hope you could explain me what I'm doing wrong and give me a solution. Thanks per advance.

No more words but my code will be helpful...

My user control :

BaseConnection.xaml

<UserControl x:Class="WpfCommonControls.Utils.UserControls.BaseConnection"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfCommonControls.Utils.UserControls"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="400"
             x:Name="BaseConnectionUserControl">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/UserControlsResources.en-EN.xaml"/>
                <ResourceDictionary Source="Resources/UserControlsResources.fr-FR.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <StackPanel Orientation="Vertical">
            <Label x:Name="lbl_Connection_uc" Padding="0"
                   Content="{DynamicResource LabelBaseConnection}"/>
            <ComboBox x:Name="cbbox_Connections_uc" Margin="0 5 5 0"
                      ItemsSource="{Binding ElementName=BaseConnectionUserControl, Path=UcConnectionList}"
                      SelectedValuePath="Name"
                      SelectedValue="{Binding ElementName=BaseConnectionUserControl, Path=UcConnectionName, UpdateSourceTrigger=PropertyChanged}"
                      DisplayMemberPath="Name">
            </ComboBox>
        </StackPanel>
    </Grid>
</UserControl>

BaseConnection.xaml.cs

namespace WpfCommonControls.Utils.UserControls
{
    /// <summary>
    /// Interaction logic for BaseConnection.xaml
    /// </summary>
    public partial class BaseConnection : UserControl
    {

        #region Properties
        public static readonly DependencyProperty ConnectionNameProperty = DependencyProperty.Register("UcConnectionName", typeof(String), typeof(BaseConnection));

        public String UcConnectionName
        {
            get
            {
                return (String)GetValue(ConnectionNameProperty);
            }
            set
            {
                SetValue(ConnectionNameProperty, value);
            }
        }

        public static readonly DependencyProperty ConnectionListProperty = DependencyProperty.Register("UcConnectionList", typeof(List<UcConnection>), typeof(BaseConnection));

        public List<UcConnection> UcConnectionList
        {
            get
            {
                return (List<UcConnection>)GetValue(ConnectionListProperty);
            }
            set
            {
                SetValue(ConnectionListProperty, value);
            }
        }


        public static readonly DependencyProperty TypeOfDatabaseProperty = DependencyProperty.Register("TypeOfDatabase", typeof(DataBaseType), typeof(BaseConnection));

        public DataBaseType TypeOfDatabase
        {
            get
            {
                return (DataBaseType)GetValue(TypeOfDatabaseProperty);
            }
            set
            {
                SetValue(TypeOfDatabaseProperty, value);
            }
        }

        #endregion Properties

        #region Private Properties
        private String _languageCode = "en-EN";
        private CultureHelper _cultureHelper = new CultureHelper();
        private UcConnection _ucConnection = new UcConnection();
        #endregion Private Properties
        public BaseConnection()
        {
            InitializeComponent();
            _languageCode = Thread.CurrentThread.CurrentCulture.Name;
            this.Resources = _cultureHelper.FindRessourcesDictionnary(this.Resources, "UserControlsResources", _languageCode);
            List<UcConnection> connectionListByDatabaseType = new List<UcConnection>();
            switch (TypeOfDatabase)
            {
                case DataBaseType.MySql:
                    foreach (UcConnection ucConnection in UcConnectionList)
                    {
                        if (ucConnection.DriverName.ToLower().Contains("mysql"))
                        {
                            connectionListByDatabaseType.Add(ucConnection);
                        }
                    }
                    UcConnectionList = connectionListByDatabaseType;
                    
                    break;
                case DataBaseType.SqlServer:
                    break;
                default:
                    break;

            }
        }

        public BaseConnection(String connectionName, List<UcConnection> connections)
        {
            InitializeComponent();
            UcConnectionList = connections;
            connectionName = UcConnectionName;
            _languageCode = Thread.CurrentThread.CurrentCulture.Name;
            this.Resources = _cultureHelper.FindRessourcesDictionnary(this.Resources, "UserControlsResources", _languageCode);
        }
    }
}

My Enum UserControlEnum.cs

namespace WpfCommonControls.Utils.UserControls
{
    /// <summary>
    /// Enumeration for the databasetype to display in the base connection combobox
    /// </summary>
    public enum DataBaseType
    {
        [Description("All available connections")]
        All = 0,
        [Description("Only MySql connections")]
        MySql = 1,
        [Description("Only Sql server connections")]
        SqlServer = 2
    }
}

My UcConnection class UcConnection.cs

namespace WpfCommonControls.CommonClasses
{
    public class UcConnection
    {
        public String Name { get; set; }
        public String ServerName { get; set; }
        public String ServerPort { get; set; }
        public String DatabaseName { get; set; }
        public String UserName { get; set; }
        public String UserPassword { get; set; }
        public String DriverName { get; set; }

        public UcConnection()
        {

        }
        public UcConnection(String nameConnection, String serverName, String serverPort, String databaseName, String userName, String userPassword, String driverName)
        {
            Name = nameConnection;
            ServerName = serverName;
            ServerPort = serverPort;
            DatabaseName = databaseName;
            UserName = userName;
            UserPassword = userPassword;
            DriverName = driverName;
        }


        public List<UcConnection> UcConnections
        {
            get
            {
                return _UcConnections;
            }
            set
            {
                _UcConnections = value;
            }
        }

        private List<UcConnection> _UcConnections = new List<UcConnection>();
        public static UcConnection GetUcConnection(String name, List<UcConnection> connections)
        {
            UcConnection selectedConnection = new UcConnection();
            if (connections == null)
            {
                connections = new List<UcConnection>();
            }

            foreach (UcConnection cn in connections)
            {
                if (cn.Name == name)
                {
                    selectedConnection = cn;
                    break;
                }
            }

            return selectedConnection;
        }
    }

}

How I used my user control in the window

xmlns:commonUserControls="clr-namespace:WpfCommonControls.Utils.UserControls;assembly=WpfCommonControls"
<commonUserControls:BaseConnection x:Name="uc_BaseConnection"
                                   UcConnectionList="{Binding Path=ConnectionList}"
                                   UcConnectionName="{Binding Path = ConnectionName, UpdateSourceTrigger = Explicit, Mode=TwoWay}"
                                   TypeOfDatabase="MySql"/>

In BaseConnection.xaml.cs, I've tried this but didn't solve the problem

public static readonly DependencyProperty TypeOfDatabaseProperty = DependencyProperty.Register("TypeOfDatabase", typeof(DataBaseType), typeof(BaseConnection), new PropertyMetadata(DataBaseType.All, new PropertyChangedCallback(OnTypeOfDatabaseChanged)));

        private static void OnTypeOfDatabaseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (BaseConnection)d;
            control.TypeOfDatabase = (DataBaseType)e.NewValue;
        }

        public DataBaseType TypeOfDatabase
        {
            get
            {
                return (DataBaseType)GetValue(TypeOfDatabaseProperty);
            }
            set
            {
                SetValue(TypeOfDatabaseProperty, value);
            }
        }

Solution

  • You switch on TypeOfDatabase in the constructor before the property has been set.

    Move the switch statement to the OnTypeOfDatabaseChanged callback or to a Loaded event handler:

    public BaseConnection()
    {
        InitializeComponent();
        _languageCode = Thread.CurrentThread.CurrentCulture.Name;
        this.Resources = _cultureHelper.FindRessourcesDictionnary(this.Resources, "UserControlsResources", _languageCode);
    
        Loaded += OnLoaded;
    }
    
    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        List<UcConnection> connectionListByDatabaseType = new List<UcConnection>();
        switch (TypeOfDatabase)
        {
            case DataBaseType.MySql:
                foreach (UcConnection ucConnection in UcConnectionList)
                {
                    if (ucConnection.DriverName.ToLower().Contains("mysql"))
                    {
                        connectionListByDatabaseType.Add(ucConnection);
                    }
                }
                UcConnectionList = connectionListByDatabaseType;
    
                break;
            case DataBaseType.SqlServer:
                break;
            default:
                break;
    
        }
    }