1

我正在使用带有 ModelView-First 方法的 MVVM 模式。到目前为止,这工作正常。现在我有一个 UserControl(视图),它应该根据位于我的 ViewModel 中的属性显示各种内容。

首先,我尝试使用 DataTemplates 和 DataTemplateSelector 解决问题(请参阅本教程),效果很好。但我对解决方案不满意,因为那时我有一个类(被覆盖的 DataTemplateSelector),它没有连接到 ViewModel 并且无法从模型中填充。

所以我尝试创建一个自己的 TemplateSelector,它使用 ViewModel 中的一个属性。不幸的是,DataTrigger 没有触发。从 CheckBox 到 ViewModel 的绑定也可以工作,但不能在 DataTrigger 上工作(即使设计者也找不到此路径)。

好的,请看代码:

<UserControl.Resources>     
        <!--Define Template which is displayed for Users-->
        <DataTemplate x:Key="templateUser">     
            <Image 
                Name="logo"
                Source="blanked out"
                HorizontalAlignment="Center" 
                VerticalAlignment="Center" />
        </DataTemplate>

        <!--Define Template which is displayed for Administrators-->
        <DataTemplate x:Key="templateAdmin">
            <TextBlock Background="Yellow" Margin="3" Text="YEAH, I'm an Administrator" />
        </DataTemplate>

        <!--My own TemplateSelectpr-->
        <DataTemplate x:Key="myTemplateSelector">
            <ContentControl x:Name="DynamicContent" ContentTemplate="{StaticResource templateUser}"/>

            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding Path=IsAdministrator}" Value="true">
                    <Setter TargetName="DynamicContent" Property="ContentTemplate" Value="{StaticResource templateAdmin}" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
            <ContentPresenter ContentTemplate="{StaticResource myTemplateSelector}"/>
    </Grid> 

当然,我可以将任务分成两个进一步的内容控件,但如果相同的内容相交,我不想维护它们。那么有人可以提出任何建议吗?

最好的问候,并提前感谢!

4

2 回答 2

1

答案是渴望评论

Arnaud Weil 让我走上了正确的道路:

为了从数据模板访问 ViewModel 中的属性“IsAdministrator”,我给了 UserControl 一个名称,例如:

<UserControl    
    x:Class="blanked out"
    x:Name="this"

使用 Arnaud 的代码进行了一些修改,以从 UserControl 继承到 ViewModel 的绑定

<UserControl.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
        <helper:NotBooleanToVisibilityConverter x:Key="NotBooleanToVisibilityConverter"/>
        <DataTemplate x:Key="myTemplate">
            <Grid>
                <Grid Visibility="{Binding DataContext.IsAdministrator, ElementName=this, Converter={StaticResource BooleanToVisibilityConverter}}">
                    <!-- Content for admin -->
                    <TextBlock Background="Yellow" Margin="3" Text="ICH BIN ADMNIN; JUCHUUU" />
                </Grid>
                <Grid Visibility="{Binding DataContext.IsAdministrator, ElementName=this, Converter={StaticResource NotBooleanToVisibilityConverter}}">
                    <!-- Content for user -->
                    <Image 
                        Name="logo"
                        Source="/blanked out"
                        HorizontalAlignment="Center" 
                        VerticalAlignment="Center" />
                </Grid>
            </Grid>
        </DataTemplate>
    </UserControl.Resources>

对于倒置的 BooleanToVisibilityConverter:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace blankedout.Helper
{
    [ValueConversion(typeof(bool), typeof(Visibility))]
    public class NotBooleanToVisibilityConverter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var boolValue = (bool)value;
            return !boolValue ? Visibility.Visible : Visibility.Hidden;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

再次感谢 Arnaud Weil

问候

于 2012-08-09T08:38:13.087 回答
1

越简单越好:使用单个模板,其中包含您需要显示的所有控件。然后使用绑定到您的属性来切换它们的可见性:

<UserControl.Resources>
    <DataTemplate x:Key="myTemplate">
      <Grid>
        <Grid Visibility="{Binding IsAdministrator, Converter={StaticResource BooleanToVisibilityConverter}}">
           <!-- Content for admin -->
        </Grid>
        <Grid Visibility="{Binding IsAdministrator, Converter={StaticResource NotBooleanToVisibilityConverter}}">
           <!-- Content for user -->
        </Grid>
      </Grid>
    </DataTemplate>
</UserControl.Resources>

<Grid>
        <ContentPresenter ContentTemplate="{StaticResource myTemplate}"/>
</Grid> 
于 2012-08-08T08:19:37.850 回答