0
votes

I am adding the user controls during runtime based on a query of a database of XML data. So, the number of user controls is different.

Also, given the type of XML received, I cannot bind the user control to the list created from the XML data because there will instances where I will pull different fields based on whether this is a new client versus an existing client. For an existing client, there are only 8 fields. A new client needs 40 or 50 fields.

I am creating one of two user control based on new client versus the existing client.

I believe this is what is needed on the user control.

Here is the code snippet.

public event RoutedEventHandler btnAddClient_Click;

private void OnButtonClick(object sender, RoutedEventArgs e)
{
    if(btnAddClient_Click !=null)
        {
            btnAddClient_Click(this, new RoutedEventArgs());
        }
}
public ucNewClient()
{
    InitializeComponent();
}

I need to know how to set the click event on the dynamically created user control and also the main form.

Any help would be greatly appreciated.

I have done multiple research and did not find help. What I found were user controls with a click event. However, the user control was not dynamically/during runtime.

I expect to perform an action of adding or updating a client to a list to perform tasks later in the project.

1
may be will be better to create control in design time and run time just show or hide it? - Zam

1 Answers

0
votes

Welcome to SO.

Any time you need to render a list of items in WPF you should use ItemsControl or one of it's derived classes. Start with a list of the data elements you want to display in your view model (or whatever your DataContext is set to):

    private ObservableCollection<SomeBaseClass> _MyItems;
    public ObservableCollection<SomeBaseClass> MyItems
    {
        get { return this._MyItems; }
        set
        {
            if (this._MyItems != value)
            {
                this._MyItems = value;
                RaisePropertyChanged(() => this.MyItems);
            }
        }
    }

You then declare an ItemsControl that binds to this list:

 <ItemsControl ItemsSource="{Binding MyItems}" />

A vertical stackpanel is the default layout panel, but you can change that to something else if you need. Either way you then create a data template for each type of data you want to display:

<Window.Resources>

    <DataTemplate DataType="{x:Type local:DataTypeA">
        <TextBlock Text="This is data type A" />
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:DataTypeB">
        <TextBlock Text="This is data type B" />
    </DataTemplate>

   ... etc ...

</Window.Resources>

And that's it!

Sometimes you'll want to display things differently depending on actual data itself, and in that case you can use a single data template with data triggers instead:

<ControlTemplate x:Key="TemplateA">
    <TextBlock Text="This is template A" />
</ControlTemplate>

<ControlTemplate x:Key="TemplateB">
    <TextBlock Text="This is template B" />
</ControlTemplate>

<DataTemplate DataType="{x:Type local:SomeBaseClass}">
    <ContentControl Content="{Binding}">
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding SomeProperty}" Value="ValueA">
                        <Setter Property="Template" Value="{StaticResource TemplateA}" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding SomeProperty}" Value="ValueB">
                        <Setter Property="Template" Value="{StaticResource TemplateB}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>
</DataTemplate>