WPF:如果为 null,则更改数据上下文

本文关键字:数据 上下文 如果 null WPF | 更新日期: 2023-09-27 18:33:54

我有一个视图,我想为其分配一个"备份"视图模型。本质上,如果"通用"为空,我想将数据上下文设置为"通用工厂"。"GenericFactory"能够创建"Generic"视图模型的实例。创建视图模型后,视图模型被分配给适当的属性并触发 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;
    }
}

谢谢 - 德里克

WPF:如果为 null,则更改数据上下文

感谢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();
    }
}
我不知道

你的工厂是如何工作的,所以这可能不是工作代码,但你应该在视图模型中处理这个逻辑,你的视图应该只设置数据上下文。

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

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

如果您的工厂具有返回 ViewModel 的同步创建,那么那会更好,因为泛型永远不会返回 null。 _generic = GenericFactory.Create();