WPF:如果Null改变DataContext?

时间:2014-12-09 20:02:18

标签: c# wpf xaml mvvm

我认为我想分配一个"备份" viewmodel到。基本上如果" Generic"是null我想将DataContext设置为" GenericFactory"。 " GenericFactory"能够创建" Generic"的实例。视图模型。在创建时,viewmodel被分配给相应的属性并且触发了PropertyChanged事件,但是在下面的代码中,我曾经绑定的唯一DataContext是" GenericFactory"。任何人都可以解释和/或提供替代解决方案吗?

XAML

<Page x:Class="GenericProject.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:vw="clr-namespace:GenericProject.View">
    <StackPanel>
        <!--Additional markup-->
        <vw:GenericView>
            <vw:GenericView.Style>
                <Style TargetType="{x:Type vw:GenericView}">
                    <Setter Property="DataContext" Value="{Binding Generic}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Generic}" Value="{x:Null}">
                            <Setter Property="DataContext" Value="{Binding GenericFactory}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </vw:GenericView.Style>
        </vw:GenericView>
    </StackPanel>
</Page>

视图模型

public class MainPageViewModel : ViewModelBase
{
    public GenericViewModel Generic
    {
        get { return _generic; }
        private set
        {
            if (_generic != value)
            {
                _generic = value;
                base.OnPropertyChanged("Generic");
            } 
        }
    }

    public GenericFactoryViewModel GenericFactory { get; private set; }

    private void OnGenericFactoryCreatedGeneric(object sender, CreatedGenericEventArgs e)
    {
        Generic = e.Generic;
    }

    public MainPageViewModel()
    {
        GenericFactory = new GenericFactoryViewModel();
        GenericFactory.CreatedGeneric += OnGenericFactoryCreatedGeneric;
    }
}

谢谢 - 德里克

2 个答案:

答案 0 :(得分:1)

感谢XAMIMAX的评论,我能够找到使用PriorityBinding的解决方案。

XAML

<Page x:Class="GenericProject.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="clr-namespace:GenericProject"
      xmlns:vw="clr-namespace:GenericProject.View">
    <Page.Resources>
        <local:NullToDependencyPropertyUnsetConverter x:Key="NullToDependencyPropertyUnsetConverter" />
    </Page.Resources>
    <StackPanel>
        <!--Additional markup-->
        <vw:GenericView>
            <vw:GenericView.DataContext>
                <PriorityBinding>
                    <Binding Path="Generic" Converter="{StaticResource NullToDependencyPropertyUnsetConverter}" />
                    <Binding Path="GenericFactory" />
                </PriorityBinding>
            </vw:GenericView.DataContext>
        </vw:GenericView>
    </StackPanel>
</Page>

转换器

public class NullToDependencyPropertyUnsetConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value ?? DependencyProperty.UnsetValue;
    }

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

答案 1 :(得分:0)

我不知道你的工厂是如何工作的,所以这可能不是代码,但你应该在视图模型中处理这个逻辑,你的视图应该只设置datacontext。

public GenericViewModel Generic
    {
        get 
        { 
            if(_generic == null)
            {
                GenericFactory.Create();
            }
            return _generic;
        }
        private set
        {
            if (_generic != value)
            {
                _generic = value;
                base.OnPropertyChanged("Generic");
            }
        }
    }

这将为Generic返回null,但是当调用OnGenericFactoryCreatedGeneric时,它将设置Generic,然后使绑定更新为新创建的视图模型。

如果你的工厂有一个返回ViewModel的同步创建,那么这将更好,因为Generic永远不会返回null。 _generic = GenericFactory.Create();