Hi Jenny,
you can include UserControls in XAML files (ResourceDictionary) and load this files on demand into List of UserControls. If you want to use random for selecting after loading files you can use List.Count like this:
int _num = new Random().Next(0,ListOfUserControls,Count);
Try following demo:
ViewModel:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
namespace WpfApp2
{
public class ViewModel : ICommand, INotifyPropertyChanged
{
public ViewModel()
{
LoadListOfUserControls();
}
public Dictionary<string, UserControl> ListOfControls { get; set; }
private void LoadListOfUserControls()
{
ListOfControls = new Dictionary<string, UserControl>();
foreach (var fi in Directory.GetFiles(@"UCResources"))
{
var dict = (ResourceDictionary)XamlReader.Load(new FileStream(fi, FileMode.Open));
foreach (DictionaryEntry item in dict)
{
var uc = item.Value as UserControl;
if (uc != null) ListOfControls.Add(item.Key.ToString(), uc);
}
}
}
private UserControl _actualUserControl = null;
public UserControl ActualUserControl
{
get => this._actualUserControl;
set { this._actualUserControl = value; OnPropertyChanged(); }
}
public void Execute(object parameter) =>
ActualUserControl = ((KeyValuePair<string, UserControl>)parameter).Value;
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => true;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
XAML:
<Window x:Class="WpfApp2.MainWindow"
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"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="558" Width="718" Background="AliceBlue">
<Window.Resources>
<local:ViewModel x:Key="vm"/>
</Window.Resources>
<Grid DataContext="{StaticResource vm}">
<Menu Name="menu1" Width="343" Margin="76,110,0,0"
HorizontalAlignment="Left" VerticalAlignment="Top"
FontFamily="Times New Roman" FontSize="20"
Background="#FF00F500"
ItemsSource="{Binding ListOfControls}">
<Menu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Key}" />
<Setter Property="Command" Value="{Binding Source={StaticResource vm}}" />
<Setter Property="CommandParameter" Value="{Binding}" />
</Style>
</Menu.ItemContainerStyle>
</Menu>
<UserControl Height="190" Width="490" Margin="74,184,118,133"
Background="Aqua">
<Grid Name="grid2" Height="185" Width="485"
Background="#FFFDD293">
<TextBlock Name="textBlock1"
Text="User Control Area"
Height="30" Width="180"
HorizontalAlignment="Left" VerticalAlignment="Top"
FontFamily="Times New Roman" FontSize="22"
Background="#FFFFCD00"/>
<ContentControl Content="{Binding ActualUserControl}"/>
</Grid>
</UserControl>
</Grid>
</Window>
UserControls are included in ResourceDictionary in SubFold "UCResources" like this:
<ResourceDictionary 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">
<UserControl x:Key="UC1">
<Grid>
<TextBlock Text="User Control 1" TextWrapping="Wrap"
Height="28" Width="142" Margin="66,102,0,0"
HorizontalAlignment="Left" VerticalAlignment="Top"
Background="#FF97E3F3"/>
</Grid>
</UserControl>
<UserControl x:Key="UC2">
<Grid>
<TextBlock Text="User Control 2" TextWrapping="Wrap"
Height="28" Width="142" Margin="66,102,0,0"
HorizontalAlignment="Left" VerticalAlignment="Top"
Background="#FFB2E68F"/>
</Grid>
</UserControl>
</ResourceDictionary>