在开始之前,我已经在 GIST 中添加了与我的问题相关的文件:https ://gist.github.com/4468651
正如标题所说,我有一个 WPF 应用程序(实现 MVVM - 或者尽可能地成为初学者),并且MainView的 Visibility 属性绑定似乎没有从它的ViewModel中提取相关值。
在启动时,会抛出一个绑定错误,表明它在实例化时没有找到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添加到绑定中,但这并没有减轻警告或问题。我还尝试直接更改为提供System.Windows.Visibility值的属性,以使用数据触发器检查布尔属性并相应地设置可见性,这也没有改变问题或警告消息。
加载完所有内容后,如果我在托盘图标上调出上下文菜单并单击“*隐藏窗口”或“显示窗口” (它应该通知MainView它需要隐藏或显示)什么都不会发生。这就是我m 期望在代码中发生(仅引用与问题相关的文件):
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 中抛出异常来检查这一点)。
我很茫然,希望有任何意见!
ps https://www.dropbox.com/s/03z361qyws4jhuo/ordoFile.zip是项目文件的链接,如果有人想修改实际项目,因为我确信我没有特别清楚地解释这个问题。
Uodate(感谢 Backlash):我之前提到的错误似乎与我的MainView可见性未正确更新的问题无关。