WPF не может показать шаблон внутри DataContent - PullRequest
0 голосов
/ 07 декабря 2018

Я довольно новичок в WPF и уверен, что более опытные WPF-кодеры смогут обнаружить мою проблему в течение нескольких секунд.

Я пытаюсь показать UserControl внутри DataContent,объявив его шаблоном, но вместо него я получаю только:

enter image description here

вот соответствующие части моего кода:

                            <ContentControl Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="3" >
                             <DataTemplate  DataType="{x:Type ViewModels:anotherViewViewModel}">
                                  <Views:anotherView Content="{Binding}"/>
                             </DataTemplate>
                           </ContentControl>

Представление:

<UserControl x:Class="materialDesignTesting.Views.anotherView"
         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:materialDesignTesting.Views"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
  <Grid Background="Aqua">

  </Grid>
</UserControl>

, а представление модели:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace materialDesignTesting.ViewModels
{
    class anotherViewViewModel
    {
    }
}

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018

Обычно вы определяете шаблон как:

   <DataTemplate DataType="{x:Type local:FooVM}">
       <local:FooUserControl/>
   </DataTemplate>

Это входит в словарь ресурсов, который объединен в app.xaml.Затем вы связываете

<ContentControl Content="{Binding ContentProperty}"/>

. В качестве модели представления является текстовый текст, ContentProperty устанавливается на экземпляр модели представления, такой как FooVM, чтобы перейти к foo.Когда вы перемещаетесь, лучше установить ContentProperty на null, а затем на новый vm, если вы не хотите сохранять состояние просмотра, если пользователь переходит к тому же представлению.

В любом случае, когда вы делаете это, usercontrol FooUserControl, который вы производите изэтот шаблон содержит содержимое (ваш виртуальный компьютер) в виде текста.

Вот упрощенный пример:

public class MainWindowViewModel : INotifyPropertyChanged
{
    private object currentViewModel;

    public object CurrentViewModel
    {
        get { return currentViewModel; }
        set { currentViewModel = value; RaisePropertyChanged(); }
    }
    private RelayCommand<Type> navigateCommand;
    public RelayCommand<Type> NavigateCommand
    {
        get
        {
            return navigateCommand
              ?? (navigateCommand = new RelayCommand<Type>(
                vmType =>
                {
                    CurrentViewModel = null;
                    CurrentViewModel = Activator.CreateInstance(vmType);
                }));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Представление:

<Window x:Class="wpf_Navigation_ViewModelFirst.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:wpf_Navigation_ViewModelFirst"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <DataTemplate DataType="{x:Type local:LoginViewModel}">
        <local:LoginUC/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:UserViewModel}">
        <local:UserUC/>
    </DataTemplate>
</Window.Resources>
<Window.DataContext>
    <local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <StackPanel>
        <Button Content="Login Page"
                Command="{Binding NavigateCommand}"
                CommandParameter="{x:Type local:LoginViewModel}"
                />
        <Button Content="User Page"
                Command="{Binding NavigateCommand}"
                CommandParameter="{x:Type local:UserViewModel}"
                />
    </StackPanel>
    <ContentControl Grid.Column="1"
                    Content="{Binding CurrentViewModel}"
                    />
</Grid>

0 голосов
/ 07 декабря 2018
<ContentControl Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="3" >
    <DataTemplate  DataType="{x:Type ViewModels:anotherViewViewModel}">
          <Views:anotherView Content="{Binding}"/>
    </DataTemplate>
</ContentControl>

Устанавливает DataTemplate в качестве фактического содержимого элемента управления контентом.Вам необходимо свойство ContentTemplate (или установить ресурсы):

<ContentControl Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="3" >
    <ContentControl.ContentTemplate>
    <DataTemplate  DataType="{x:Type ViewModels:anotherViewViewModel}">
          <Views:anotherView Content="{Binding}"/>
    </DataTemplate>
    </ContentControl.ContentTemplate>
</ContentControl>

, которое работает, только если для свойства Content ContentControl задан экземпляр anotherViewModel.Так как он не связан или что-то в этом коде, я предполагаю, что он все еще нулевой, и поэтому не будет создавать экземпляр вашего представления.

Вы могли бы просто использовать Views:anotherView непосредственно как @Silvermindпредлагает, но я подозреваю, что вы собираетесь на какое-то динамическое переключение.Если вы хотите придерживаться своего текущего подхода, просто дайте ContentControl что-то для отображения!

Соответственно, если anotherView не является также a ContentControl, это вероятноне имеет свойства Content, так что set / binding - это нонсенс.anotherView выберет экземпляр anotherViewModel в качестве своего DataContext, поскольку он находится в шаблоне данных, который у вас есть, никакого дополнительного кода не требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...