将DataTemplate项目事件绑定到ViewModel中的命令

时间:2019-08-31 15:03:18

标签: wpf xaml

Iam Building WPF MVVM应用程序具有一个列表框,该列表框的项目模板具有组合框和文本框(项目模板位于单独的资源字典中),我将模板中的selectionchanged事件和textchanged事件绑定到了我的viewmodel中的命令,在运行时可以完美运行,但是问题是在设计时它会给我triggers.null错误,xamlview不会显示,但是会给我XamlParseException。

i我在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'为空。

这是ViewModel:

    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;
}

2 个答案:

答案 0 :(得分:1)

问题是通过使用.NET 4的Microsoft Expression Blend软件开发工具包(SDK)中的交互性dll解决的,可以在此处下载“ https://www.microsoft.com/en-us/download/details.aspx?id=10801”,问题很简单,就是旧的交互性dll不支持x64(这是我的项目体系结构),但是这个新的支持。感谢@BionicCode从一开始就通过分享想法和支持我来帮助我。

答案 1 :(得分:0)

从列表框中删除itemssource可以解决问题,但不知道将itemsource放在哪里以确保在运行时绑定而不会出现此错误