【发布时间】:2019-08-31 15:03:18
【问题描述】:
我正在构建具有列表框的 WPF MVVM 应用程序,该列表框的项目模板具有组合框和文本框(项目模板位于单独的资源字典中),我将模板中的 selectionchanged 事件和 textchanged 事件绑定到我的视图模型中的命令,它是在运行时完美运行,但问题是在设计时它给了我 triggers.null 错误,xamlview 没有显示但给了我 XamlParseException。
我在 MVVMlight 中尝试了 CommandtoEvent,但没有成功,还尝试了 AttachedCommandBehavior,但也没有成功,此外还尝试将整个模板移动到视图中(作为视图中的项目模板而不是资源字典,但没有也不行。
听起来交互性在放置在模板中时会出现此错误,但我不知道如何解决它
附加的 Xaml 代码用于列表框的数据模板
<DataTemplate x:Key="AllPanelsFilter">
<Grid Margin="0 0 30 0" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox ItemsSource="{Binding AllConditionsList}" SelectedItem="{Binding SelectedCondition}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged" >
<i:InvokeCommandAction Command="{Binding DataContext.ApplyAllPanelsFiltersCommand, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor} }"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
<TextBox Grid.Row="1" Style="{StaticResource SearchTextBox}" Text="{Binding SearchString, UpdateSourceTrigger=PropertyChanged}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding DataContext.ApplyAllPanelsFiltersCommand, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor} }"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</Grid>
</DataTemplate>
我收到此错误 >> 'System.Windows.Controls.ComboBox'.'Triggers' 为空。
这是视图模型:
public ObservableCollection<ViewNewPanelsPair> AllViewNewPanelsPairs { get; set; }
public ViewNewPanelsPair CurrentViewNewPanelsPair { get; set; }
public View CurrentView { get; set; }
public ViewsFilter ViewsFilter { get; set; }
public ViewsFilterCommand ViewsFilterCommand { get; set; }
public AddAllPanelsFilterCommand AddAllPanelsFilterCommand { get; set; }
public RemoveAllPanelsFilterCommand RemoveAllPanelsFilterCommand { get; set; }
public ApplyAllPanelsFiltersCommand ApplyAllPanelsFiltersCommand { get; set; }
public ObservableCollection<AllPanelsFilter> AllPanelsFilters { get; set; }
private AllPanelsFilter selectedAllPanelsFilter;
public AllPanelsFilter SelectedAllPanelsFilter
{
get { return selectedAllPanelsFilter; }
set
{
selectedAllPanelsFilter = value;
OnPropertyChanged("selectedAllPanelsFilter");
}
}
public LevelPanelsViewModel(List<FamilyInstance> allPanels, List<FamilyInstance> oldOanels, List<ViewNewPanelsPair> allViewNewPanelsPairs, View currentView)
{
this.FilteredAllPanels = new ObservableCollection<FamilyInstance>(allPanels);
this.AllPanels = new ObservableCollection<FamilyInstance>(allPanels);
this.OldPanels = new ObservableCollection<FamilyInstance>(oldOanels);
this.AllViewNewPanelsPairs = new ObservableCollection<ViewNewPanelsPair>(allViewNewPanelsPairs);
this.ViewNewPanelsPairs = new ObservableCollection<ViewNewPanelsPair>(allViewNewPanelsPairs);
this.CurrentView = currentView;
this.ViewsFilter = new ViewsFilter();
this.ViewsFilterCommand = new ViewsFilterCommand(this, this.ViewsFilter);
this.ViewsFilterCommand.Execute(null);
this.CurrentViewNewPanelsPair = this.ViewNewPanelsPairs[0] ; // makes first view selected at startup
this.AllPanelsFilters = new ObservableCollection<AllPanelsFilter>();
this.AddAllPanelsFilterCommand = new AddAllPanelsFilterCommand(this);
this.RemoveAllPanelsFilterCommand = new RemoveAllPanelsFilterCommand(this);
this.ApplyAllPanelsFiltersCommand = new ApplyAllPanelsFiltersCommand(this);
}
public LevelPanelsViewModel()
{
}
public void DragOver(IDropInfo dropInfo)
{
GongHelper.DragOverCopy(dropInfo);
}
public void Drop(IDropInfo dropInfo)
{
GongHelper.DropDefault(dropInfo);
//GongHelper.DropCopy<FamilyInstance>(dropInfo);
// CurrentViewNewPanelsPair.IsViewPanelsNotEmpty = CurrentViewNewPanelsPair.SelectedNewPanels.Count > 0;
}
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
这里是命令类:
public class ApplyAllPanelsFiltersCommand : ICommand
{
public LevelPanelsViewModel VM { get; set; }
public ObservableCollection<AllPanelsFilter> AllPanelsFilters { get; set; }
public List<FamilyInstance> TemporaryAllPanels { get; set; }
public ApplyAllPanelsFiltersCommand(LevelPanelsViewModel VM)
{
this.VM = VM;
this.AllPanelsFilters = VM.AllPanelsFilters;
this.TemporaryAllPanels = new List<FamilyInstance>(VM.AllPanels);
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
this.TemporaryAllPanels = new List<FamilyInstance>(VM.AllPanels);
foreach (AllPanelsFilter AllPanelsFilter in AllPanelsFilters)
{
string FilterText = AllPanelsFilter.SearchString;
if (!string.IsNullOrEmpty(FilterText))
{
switch (AllPanelsFilter.SelectedCondition)
{
case AllPanelsFilter.Contains:
TemporaryAllPanels = TemporaryAllPanels.Where(x => x.Name.ToLower().Contains(FilterText.ToLower())).ToList();
break;
case AllPanelsFilter.DoesNotContain:
TemporaryAllPanels = TemporaryAllPanels.Where(x => !x.Name.ToLower().Contains(FilterText.ToLower())).ToList();
break;
case AllPanelsFilter.BeginsWith:
TemporaryAllPanels = TemporaryAllPanels.Where(x => x.Name.ToLower().StartsWith(FilterText.ToLower())).ToList();
break;
case AllPanelsFilter.DoesNotBeginWith:
TemporaryAllPanels = TemporaryAllPanels.Where(x => !x.Name.ToLower().StartsWith(FilterText.ToLower())).ToList();
break;
case AllPanelsFilter.EndsWith:
TemporaryAllPanels = TemporaryAllPanels.Where(x => x.Name.ToLower().EndsWith(FilterText.ToLower())).ToList();
break;
case AllPanelsFilter.DoesNotEndWith:
TemporaryAllPanels = TemporaryAllPanels.Where(x => !x.Name.ToLower().EndsWith(FilterText.ToLower())).ToList();
break;
}
}
}
//clear all panels observable collection
int count = VM.FilteredAllPanels.Count;
for (int i = 0; i < count; i++)
{
VM.FilteredAllPanels.RemoveAt(0);
}
//sort temporary list
TemporaryAllPanels.OrderBy(x => x.Name);
//fill observable collection from temporary list
TemporaryAllPanels.ForEach(x => VM.FilteredAllPanels.Add(x));
}
public event EventHandler CanExecuteChanged;
}
AllPanelsFilter 类:
public class AllPanelsFilter : INotifyPropertyChanged
{
public const string Contains = "contains";
public const string DoesNotContain = "does not contain";
public const string BeginsWith = "begins with";
public const string DoesNotBeginWith = "does not begin with";
public const string EndsWith = "ends with";
public const string DoesNotEndWith = "does not end with";
public List<string> AllConditionsList { get; set; }
private string searchString;
public string SearchString
{
get { return searchString; }
set
{
searchString = value;
OnPropertyChanged("SearchString");
}
}
private string selectedCondition;
public string SelectedCondition
{
get { return selectedCondition; }
set
{
selectedCondition = value;
OnPropertyChanged("SelectedCondition");
}
}
public AllPanelsFilter()
{
this.SearchString = "";
this.AllConditionsList = new List<string>() { Contains, DoesNotContain, BeginsWith, DoesNotBeginWith, EndsWith, DoesNotEndWith };
this.SelectedCondition = Contains;
}
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
【问题讨论】:
-
设置
DataTemplate.DataType属性:DataTemplate DataType="MyViewModelType" />以在设计期间获得设计人员支持。 -
@BionicCode ,感谢您的快速回复,我这样做了
<DataTemplate x:Key="AllPanelsFilter" DataType="{x:Type VM:LevelPanelsViewModel}">但不幸的是它没有用!! -
鉴于代码正在构建和执行,并且只有设计器显示错误错误,您可以尝试清理和重建解决方案并重新启动 VS。
ApplyAllPanelsFiltersCommand声明在哪个类型上,LevelPanelsViewModel? -
@BionicCode ,回答您的问题:是的
ApplyAllPanelsFiltersCommand在LevelPanelsViewModel中声明,我尝试清理、重建和重新启动 VS,但这也没有用。 -
@BionicCode 找出导致问题的原因我尝试了这个:我从头开始新的 WPF 项目并尝试在内部添加交互性和一个模板,并且在设计时和运行时运行良好,但我发现新项目具有 AnyCpu 处理器架构,我将其转换为 X64(与我的原始项目相同),它再次给了我同样的错误,但问题是当我恢复到我的原始项目并将其从 x64 更改为 AnyCPU 希望这解决了它,令我惊讶的是它没有解决问题! ,我真的很困惑,没有想法。