У вас только 2 проблемы с этим кодом.
1) Вы не можете установить видимость пользовательского контроля напрямую ... вы должны установить его для контейнера:
<Grid Visibility="Collapsed">
<myControls:MyUserControl />
</Grid>
2) Видимость не является логическим значением, это перечисление. Таким образом, вам нужно будет использовать конвертер для преобразования логического значения в видимость. Обратите внимание:
<Window ...>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
</Window.Resources>
<Grid Visibility="{Binding ShouldShowUsercontrol1, Converter={StaticResource BoolToVis}}">
<myControls:MyUserControl />
</Grid>
</Window>
Так и должно быть. Надеюсь, это поможет.
Есть и другие вещи, о которых вы оставляете подсказки, которые могут повлиять на способность этого работать. Например, вы не показываете самый большой элемент контейнера ... вы все оборачиваете в StackPanel? Например, если вы упаковываете все в сетку, элементы управления будут перекрывать все слои.
Попробуйте эти изменения, которые я предлагаю ... это должно приблизить вас.
Редактировать: еще одна идея с использованием шаблонов данных
Еще одна вещь, которую вы можете сделать, - убедиться, что у вас есть уникальная ViewModel для каждого из этих представлений, которые вы хотите показать и скрыть:
public class MyFirstViewModel : ViewModel
{
}
public class MySecondViewModel : ViewModel
{
}
Затем из вашей «родительской» или «основной» ViewModel вы показываете или скрываете нужные представления благодаря наличию их в коллекции ViewModels:
public MyMainViewModel : ViewModel
{
public ObservableCollection<ViewModel> ViewsToShow
{
...
}
public void ShowFirstViewModel()
{
ViewsToShow.Add(new MyFirstViewModel());
}
}
Чтобы связать все в вашем представлении, вы должны затем датировать эти типы с помощью их пользовательских элементов управления (но это не приведет к созданию экземпляров этих представлений, если они не нужны:
<Window ...>
<Window.Resources>
<DataTemplate DataType="{x:Type myViewModels:MyFirstViewModel}">
<myViews:MyFirstView />
</DataTemplate>
<DataTemplate DataType="{x:Type myViewModels:MySecondViewModel}">
<myViews:MySecondView />
</DataTemplate>
</Window.Resources>
<ItemsControl ItemsSource="{Binding ViewsToShow}" />
</Window>
И для любых ViewModels, которые вы добавили в "ViewsToShow", представление автоматически увидит это и шаблон в соответствующем представлении. Опять же, не создавая его, пока он не понадобился.
Это, вероятно, немного чище, чем помещать все что-то одно в представление и устанавливать видимость, но это будет зависеть от того, у вас есть уникальный тип модели представления для каждого представления, что может быть не так.
При сохранении подхода DataTemplated возникает вопрос о сохранении состояния. Решение здесь состоит в том, чтобы использовать вашу ViewModel в качестве состояния элемента управления и соответственно проектировать ваши ViewModel и ваши View. Вот пример, который позволяет вам обменять свои представления с помощью DataTemplating, но переключение назад и вперед сохраняет состояние.
Предположим, у вас есть настройки из последнего раздела с 2 моделями представления, для которых определены таблицы данных. Давайте немного изменим MainViewModel:
public MyMainViewModel : ViewModel
{
public RelayCommand SwapViewsCommand
{
...
}
public ViewModel View
{
...
}
private ViewModel _hiddenView;
public MyMainViewModel()
{
View = new MyFirstViewModel();
_hiddenView = new MySecondViewModel();
SwapViewsCommand = new RelayCommand(SwapViewModels);
}
public void SwapViewModels()
{
var hidden = _hiddenView;
_hiddenView = View;
View = hidden;
}
}
И несколько изменений в основном виде. Для краткости я опустил шаблоны данных.
<Window ...>
<!-- DataTemplates Here -->
<Button Command="{Binding SwapViewsCommand}">Swap!</Button>
<ContentControl Content="{Binding View}" />
</Window>
Вот и все. Секрет в том, что я сохраняю ссылку на исходную модель вида. Таким образом, скажем, есть свойство строки в модели представления и соответствующее текстовое поле в пользовательском контроле DataTemplated с двусторонней привязкой , тогда состояние по существу будет сохранено.