1
votes

I have created a simple Silverlight user control and defined a public property AllowMultiple.

public bool AllowMultiple { get; set; }

Now, I am setting this public property in XAML as follows:

<Controls1:PeopleChooser Name="SinglePeopleChooser" AllowMultiple="False" Width="Auto" d:LayoutOverrides="Height"/>
<Controls1:PeopleChooser Name="MultiplePeopleChooser" AllowMultiple="True" Width="Auto" d:LayoutOverrides="Height"/>

I want to know, which is the best event I can get the value of this public property. I am trying to get this value inside of the constructor and trying to hide/show some controls inside my user controls but its not working.

public PeopleChooser()
{
    InitializeComponent();            

    if (AllowMultiple)
    {
        UsersListBox.Visibility = System.Windows.Visibility.Visible;
        UserTextBox.Visibility = System.Windows.Visibility.Collapsed;
        ResolveButton.Visibility = Visibility.Collapsed;               
    }
    else
    {
        UsersListBox.Visibility = System.Windows.Visibility.Collapsed;
        UserTextBox.Visibility = System.Windows.Visibility.Visible;
        ResolveButton.Visibility = Visibility.Visible;
    }

}

Probably because during constructor initialization the value of this public property has not been assigned by framework to the object.

3
I think it must be dependency property. - Hamlet Hakobyan

3 Answers

1
votes

I was able to solve it through loaded event. There is no need for dependency property. Please see the code below. I can access the properties value successfully in Loaded event.

 public PeopleChooser()
        {

            this.Loaded += PeopleChooser_Loaded;
            InitializeComponent();                     

        }


  void PeopleChooser_Loaded(object sender, RoutedEventArgs e)
        {
            if (AllowMultiple)
            {
                UsersListBox.Visibility = System.Windows.Visibility.Visible;
                UserTextBox.Visibility = System.Windows.Visibility.Collapsed;
                ResolveButton.Visibility = Visibility.Collapsed;            

            }
            else
            {
                UsersListBox.Visibility = System.Windows.Visibility.Collapsed;
                UserTextBox.Visibility = System.Windows.Visibility.Visible;
                ResolveButton.Visibility = Visibility.Visible;
            }
1
votes

Convert the public property with a backfield,

    private bool _allowMultiple;
    public bool AllowMultiple
    {
        get { return _allowMultiple; }
        set { _allowMultiple = value; }
    }

Place a break point in the setter and check is it hits on Constructor, if not you can use the Loaded event to check the same and make use of that.

1
votes

If you use a dependency property, you can bind other elements properties to the AllowMultiple property of the people chooser and use a visibility converter to show/hide them. Example:

public partial class PeopleChooser : UserControl
{
    public PeopleChooser()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty AllowMultipleProperty = DependencyProperty.Register("AllowMultiple", typeof(bool), typeof(PeopleChooser), null);
    public bool AllowMultiple
    {
        get { return (bool)GetValue(AllowMultipleProperty); }
        set { SetValue(AllowMultipleProperty, value); }
    }
}

<UserControl x:Class="TestSilverlightApplication.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400"
    xmlns:lcl="clr-namespace:TestSilverlightApplication">
    <UserControl.Resources>
        <lcl:VisibilityConverter x:Key="VisibilityConverter" />
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel Orientation="Vertical">
            <Button Click="Button_Click" Content="Toggle allow multiple" />
            <lcl:PeopleChooser x:Name="lclPeopleChooser" AllowMultiple="False"></lcl:PeopleChooser>
            <TextBlock Text="Dependent content" Visibility="{Binding AllowMultiple, ElementName=lclPeopleChooser, Converter={StaticResource VisibilityConverter}}" />
        </StackPanel>

    </Grid>
</UserControl>

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        lclPeopleChooser.AllowMultiple = !lclPeopleChooser.AllowMultiple;
    }

public class VisibilityConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool parsedValue = false;
        bool.TryParse(value.ToString(), out parsedValue);
        if (parsedValue)
        {
            return Visibility.Visible;
        }
        return Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

This way you can avoid page events and potentially bind the AllowMultiple property to a view model property and let the UI take care of itself.