1

ModelView-First アプローチで MVVM-Pattern を使用しています。これまでのところ、これはうまく機能します。これで、ViewModel にあるプロパティに応じてさまざまなコンテンツを表示する UserControl (ビュー) ができました。

まず、DataTemplates と DataTemplateSelector を使用して問題を解決しようとしました (このチュートリアルを参照してください)。これは非常にうまく機能していました。しかし、ViewModel に接続されておらず、モデルから入力できないクラス (オーバーライドされた DataTemplateSelector) があるため、このソリューションには満足できませんでした。

そこで、ViewModel のプロパティを使用する独自の TemplateSelector を作成しようとしました。残念ながら、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> 

もちろん、さらに 2 つのコンテンツ コントロールでタスクを分離することはできますが、同じコンテンツが交差している場合はそれらを維持したくありません。それで、誰かが何か提案できますか?

よろしくお願いします!

4

2 に答える 2

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 に答える
1

答えはコメントを求めることです

Arnaud Weil は私を正しい道に導いてくれました。

Datatemplate から 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 に答える