【发布时间】:2016-02-26 09:26:54
【问题描述】:
问题
我的WPF Window 中有许多按钮,单击它们时需要更改Window 上的视图,但保持不变ViewModel。昨天我尝试为此使用ControlTemplate,但人们提到我最好使用DataTemplate.
我需要通过ViewModel 进行绑定,并且我需要检查用户是否可以访问视图。
代码
这是我开始写的一些代码,但我觉得它不正确。
这是我在Window.Resources 的视图中定义的DataTemplate:
<DataTemplate x:Key="panel1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7*"/>
<ColumnDefinition Width="110*"/>
<ColumnDefinition Width="190*"/>
<ColumnDefinition Width="110*"/>
<ColumnDefinition Width="202*"/>
<ColumnDefinition Width="109*"/>
<ColumnDefinition Width="7*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="74*"/>
<RowDefinition Height="50*"/>
<RowDefinition Height="12*"/>
<RowDefinition Height="39*"/>
<RowDefinition Height="11*"/>
<RowDefinition Height="38*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Column="2" Grid.ColumnSpan="3" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Label Content="Video Set:" Foreground="#e37e6e" Grid.Column="2" Grid.ColumnSpan="3" VerticalAlignment="Center" FontSize="22" HorizontalAlignment="Center"/>
<Image Source="{Binding VideoSet}" Height="25" Width="25" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
<TextBlock Foreground="#e37e6e" FontSize="12" Text="You currently do not have a video set. Please click the button below to add a video. Please note you will not be able to create an On Demand presentation without a media file selected. " Grid.Row="1" Grid.Column="2" TextWrapping="WrapWithOverflow" TextAlignment="Center" Grid.ColumnSpan="3" />
<Button Style="{StaticResource loginButton}" Command="{Binding ScreenBack}" Foreground="White" Content="Add Video" Grid.Column="3" HorizontalAlignment="Stretch" Grid.Row="3" VerticalAlignment="Stretch" Grid.ColumnSpan="1"></Button>
</Grid>
</DataTemplate>
然后我尝试使用ContentPresenter 并绑定到DataTemplate:
<ContentPresenter Content="{Binding}" Grid.Row="3" Grid.RowSpan="1" Grid.ColumnSpan="5"/>
现在我希望能够通过ViewModel 将不同的DataTemplates 绑定到ContentPresenter,有人可以帮我解决这个问题吗?
编辑:
我可以通过如下静态资源将ContentPresenter绑定到DataTemplate:
<ContentPresenter ContentTemplate="{StaticResource panel1}" Content="{StaticResource panel1}" Grid.Row="3" Grid.RowSpan="1" Grid.ColumnSpan="5"/>
DataTemplate 如下所示:
<DataTemplate x:Key="panel1">
</DataTemplate>
但是我怎样才能从ViewModel 更改ControlPresenter 绑定?
编辑:
这是我的代码周期:
所以这里有两个数据模板:
<DataTemplate DataType="{x:Type local:ViewModelA}">
<TextBlock Foreground="#e37e6e" FontSize="12" Text="You currently do not have a video set. Please click the button below to add a video. Please note you will not be able to create an On Demand presentation without a media file selected. " Grid.Row="1" Grid.Column="2" TextWrapping="WrapWithOverflow" TextAlignment="Center" Grid.ColumnSpan="3" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelB}">
<TextBlock Foreground="#e37e6e" FontSize="12" Text="NEWWWWWWWWWWYou" Grid.Row="1" Grid.Column="2" TextWrapping="WrapWithOverflow" TextAlignment="Center" Grid.ColumnSpan="3" />
</DataTemplate>
我的 ContentControl:
<ContentControl Content="{Binding SelectedViewModel}" />
我在后面的代码中定义了我的 DataContext:
WizardViewModel _wizardViewModel = new WizardViewModel();
this.DataContext = _wizardViewModel;
在我拥有的 WizardViewModel 中:
namespace Podia2016.ViewModels
{
public class WizardViewModel : INotifyPropertyChanged
{
public object SelectedViewModel { get; set; }
ViewModelA s = new ViewModelA();
ViewModelB d = new ViewModelB();
public WizardViewModel()
{
SelectedViewModel = s;
OnPropertyChanged("SelectedViewModel");
}
//BC - BINDS TO CHANGE LECTURE.
public ICommand Next
{
get { return new DelegateCommand<object>(Next_Click); }
}
private void Next_Click(object obj)
{
SelectedViewModel = d;
OnPropertyChanged("SelectedViewModel");
}
}
public class ViewModelA : INotifyPropertyChanged
{
//BC - DEFAULT ONPROPERTYCHANGED EVENT.
public event PropertyChangedEventHandler PropertyChanged;
public ViewModelA()
{
}
/// <summary>
/// This is the standard OnPropertyChanged Event Method
/// </summary>
/// <param name="name"></param>
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
public class ViewModelB : INotifyPropertyChanged
{
//BC - DEFAULT ONPROPERTYCHANGED EVENT.
public event PropertyChangedEventHandler PropertyChanged;
public ViewModelB()
{
}
/// <summary>
/// This is the standard OnPropertyChanged Event Method
/// </summary>
/// <param name="name"></param>
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
【问题讨论】:
-
您的预期结果是什么?当您尝试使用 ContentPresenter 绑定到 DataTemplate 时发生了什么?
-
@Tyress 我只是在 ContentPresenter 中收到一条消息,说“System.Windows.Controls.ControlTemplate”,但这不是通过 ViewModel,因为我不确定该放什么。
-
@BenClarke 看看我的回答
-
@BenClarke 以及如何将 ViewModel 设置为 DataContext?
-
@Tyress 在后面的代码中,我只是像这样设置 DataContext
this.DataContext = _wizardViewModel;
标签: c# wpf xaml mvvm datatemplate