wpf - 无法让 View 的可见性接受来自其绑定(bind)的值

标签 wpf c#-4.0 mvvm

在开始之前,我已经在 GIST 中添加了与我的问题相关的文件:https://gist.github.com/4468651

正如标题所说,我有一个 WPF 应用程序(实现 MVVM - 或者尽可能地成为初学者),并且 MainView 的 Visibility 属性绑定(bind)似乎没有从它的 ViewModel 中提取相关值。

在启动时,会抛出一个绑定(bind)错误,表明它在实例化时没有找到 ViewModel(即使它已传递给构造函数)。错误如下:

System.Windows.Data Error: 23 : Cannot convert '<null>' from type '<null>' to 
type 'System.Windows.Visibility' for 'en-US' culture with default conversions; 
consider using Converter property of Binding. 

NotSupportedException:'System.NotSupportedException: EnumConverter cannot 
convert from (null).
at System.ComponentModel.TypeConverter.GetConvertFromException(Object value)
at System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, 
CultureInfo culture, Object value)
at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, 
DependencyObject targetElement, CultureInfo culture, Boolean isForward)'  

我尝试将 TargetNullValue 和 NullConverter 添加到绑定(bind)中,但这并没有减轻警告或问题。我还尝试直接更改为提供 System.Windows.Visibility 值的属性,以使用数据触发器检查 bool 属性并相应地设置可见性,这也没有改变问题或警告消息。

加载完所有内容后,如果我调出托盘图标上的上下文菜单并单击“*隐藏窗口”或“显示窗口”(它应该通知 MainView 它需要隐藏或显示),什么也不会发生。
这是我期望在代码中发生的事情(仅引用与问题相关的文件):

App.xaml.cs 文件 -
namespace ordoFile
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            this.Properties["bgStartup"] = false;

            if (e != null && e.Args.Count() > 0)
            {
                if(e.Args[0] == "-bg")
                {
                    this.Properties["bgStartup"] = true;
                }
            }

            Configs configs = new Configs();
            PresetFilters presets = new PresetFilters();
            OrganisationSyncer organisationSyncer = new OrganisationSyncer();
            TrayApp trayApp = new TrayApp(organisationSyncer, configs);
            Logger logger = new Logger();
            BackgroundOrganiser backgroundOrganiser = new BackgroundOrganiser(new DirectoryModel());
            ForegroundOrganiser foregroundOrganiser = new ForegroundOrganiser(new DirectoryModel());

            DependencyFactory.Container.RegisterInstance<Configs>("configs", configs);
            DependencyFactory.Container.RegisterInstance<PresetFilters>("presets", presets);
            DependencyFactory.Container.RegisterInstance<OrganisationSyncer>("organisationSyncer", organisationSyncer);
            DependencyFactory.Container.RegisterInstance<BackgroundOrganiser>("backgroundOrganiser", backgroundOrganiser);
            DependencyFactory.Container.RegisterInstance<ForegroundOrganiser>("foregroundOrganiser", foregroundOrganiser);
            DependencyFactory.Container.RegisterInstance<TrayApp>("trayApp", trayApp);
            DependencyFactory.Container.RegisterInstance<Logger>("logger", logger);

            MainViewModel mainViewModel = new MainViewModel(trayApp, organisationSyncer);
            MainView mainView = new MainView(configs, trayApp, mainViewModel);

            mainView.Show();
        }
    }
}

mainViewModel 变量通过 this.DataContext = mainViewModel 在 MainView 实例的构造函数中设置

MainView.xaml
<Window x:Class="ordoFile.Views.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:ordoFile.ViewModels"
        xmlns:vw="clr-namespace:ordoFile.Views"
        Title="ordoFile" 
        Name="MainWindow"
        Height="500" 
        Width="815">

    <Window.Style>
        <Style TargetType="Window">
            <Setter Property="Visibility" Value="{Binding WindowVisibility}"  />
        </Style>
    </Window.Style>

    <Grid Name="ContentGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>

        <vw:ForegroundOrganiserView Grid.RowSpan="2"/>

        <vw:BackgroundOrganiserView Grid.Row="2"/>
    </Grid>
</Window>

MainViewModel.cs
namespace ordoFile.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        TrayApp _trayApp;

        OrganisationSyncer _organisationSyncer;

        Visibility _windowVisibility;

        public MainViewModel(TrayApp trayApp, OrganisationSyncer organisationSyncer)
        {
            _trayApp = trayApp;
            _organisationSyncer = organisationSyncer;
            OnInitialise();
        }

        /// <summary>
                    /// Return visibilty staus of MainView
                    /// </summary>
        public Visibility WindowVisibility
        {
            get { return _windowVisibility; }
            set
            {
                _windowVisibility = value;
                OnPropertyChanged("WindowVisibility");
            }
        }

        void OnInitialise()
        {
            WindowVisibility = _organisationSyncer.WindowVisibilty;

            // Add method to event handler in OrganisationSyncer
            // that will be called when UI visibility is to be updated.
            _organisationSyncer.UpdateWindowVisibility += CheckVisibilityStatus;
        }

        /// <summary>
        /// Set property to visibility value held in OrganisationSyncer
        /// instance.
        /// </summary>
        void CheckVisibilityStatus(object sender, EventArgs e)
        {
            WindowVisibility = _organisationSyncer.WindowVisibilty;
        }
    }
}

所有这些似乎工作正常,调用了 setter,并且 UI 甚至尝试读取它(我通过在更新发生后抛出的 getter 中抛出异常来检查这一点)。

我很茫然,希望有任何意见!

p.s. https://www.dropbox.com/s/03z361qyws4jhuo/ordoFile.zip是项目文件的链接,如果有人想修改实际项目,因为我确信我没有特别清楚地解释这个问题。

Uodate(感谢 Backlash):我之前提到的错误似乎与我的 MainView 可见性未正确更新的问题无关。

最佳答案

从逐步开始,错误是这一行:

<Setter Property="Visibility" Value="{Binding WaitImageVisibility}" />

您的 WaitImageVisibility 是一个字符串值。您需要将其更改为 Visibility 类型(顺便说一下,您通常不会将 Visibility 用作 View 模型上的数据类型,但这没什么大不了的),或者您需要一个从字符串转换的转换器到能见度。

关于wpf - 无法让 View 的可见性接受来自其绑定(bind)的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14184998/

相关文章:

c# - 在运行时动态选择要使用的 .dll 版本

c# - View 模型中的 MVVM 异步调用 : How can I connect azure DB with MVVM

c# - 为什么在扩展 `TreeViewItem` 时调用命令不起作用?

WPF数据网格问题

c# - 类静态成员的奇怪行为——这怎么可能?

具有嵌套属性的 Wpf 绑定(bind)

c# - 在 C# 中将 HTTP Accept 和 Content-Type header 都设置为 "application/xml"

c# - 我的第一个WPF应用程序中的WPF window_loaded异常

wpf - Windows 10 所有 DPI 设置上的所有图标分辨率?格式?像素艺术作为图标?开始菜单中等磁贴中的大尺寸图标?

wpf - 循环图像旋转在 opencv 中最好的方法是什么