2015-10-06 151 views
2

我有一個列表視圖,我將多個數據模板綁定到使用DataTemplateSelector。但是,我無法構建我的項目,我收到「對象引用未設置爲對象實例」的錯誤。我將問題縮小到了組合框的數據綁定ItemsSource。如果我註釋掉組合框,我的項目就會建立。據我所知,Binding關鍵字在運行時進行評估,但這是編譯時錯誤。我嘗試通過交換到x:Bind來解決錯誤,因爲它在編譯時計算,但是之後需要定義DataTemplate的類型。XAML嵌套模板綁定

x:DataType={x:Type templates:FilterDropdownDataTemplate} 

但是,x:類型未在Windows 10通用應用程序中定義。有什麼建議麼?

這是我的XAML:

<Page.Resources> 
    <DataTemplate x:Name="DateComboboxTemplate"> 
     <TextBlock Text="{Binding}"/> 
    </DataTemplate> 

    <DataTemplate x:Name="FilterDropdownDataTemplate"> 
     <StackPanel> 
      <TextBlock Text="{Binding Value}"/> 
      <ComboBox ItemsSource="{Binding DateRanges}" 
       SelectionChanged="{Binding DateSelection}" 
       SelectedItem="{Binding SelectedDateRange, Mode=TwoWay}" 
       ItemTemplate="{StaticResource DateComboboxTemplate}"> 
      </ComboBox> 
     </StackPanel> 
    </DataTemplate> 

    <config:MainFilterTemplateSelector 
     x:Name="MainFilterSelector" 
     FilterDropdownTemplate="{StaticResource FilterDropdownDataTemplate}" 
     /> 
</Page.Resources> 

<ListView x:Name="FilterCategories" 
      Margin="0" 
      Padding="0" 
      BorderThickness="0" 
      ItemsSource="{Binding Filters}" 
      SelectedItem="{Binding SelectedFilterCategory, Mode=TwoWay}" 
      IsItemClickEnabled="True" 
      SelectionChanged="{x:Bind ViewModel.OpenSubFilters}" 
      ItemTemplateSelector="{StaticResource MainFilterSelector}"> 
</ListView> 

這裏是相關的C#代碼(我使用MVVM模式):

public class MainFilterViewDropdownListTemplate : Filter 
{ 
    private ObservableCollection<string> _dateRanges; 
    private string _selectedDateRange; 

    public MainFilterViewDropdownListTemplate() : base() 
    { 
     _dateRanges = new ObservableCollection<string>(); 
    } 

    public ObservableCollection<string> DateRanges 
    { 
     get 
     { 
      return _dateRanges; 
     } 
     set 
     { 
      SetProperty(ref _dateRanges, value); 
      // hard coding these 4 lines for testing for now 
      _dateRanges.Add("Last 7 days"); 
      _dateRanges.Add("Last 14 days"); 
      _dateRanges.Add("Last 30 days"); 
      _dateRanges.Add("Custom"); 
     } 
    } 

    public string SelectedDateRange 
    { 
     get 
     { 
      return _selectedDateRange; 
     } 
     set 
     { 
      SetProperty(ref _selectedDateRange, value); 
     } 
    } 

    public IEnumerable<Filter> AllFilters { get; set; } 

    public void InitializeFields(Filter filter) 
    { 
     Column = filter.Column; 
     DisplayType = filter.DisplayType; 
     ID = filter.ID; 
     IsSelected = filter.IsSelected; 
     ParentId = filter.ParentId; 
     SelectedCount = filter.SelectedCount; 
     TotalCount = filter.TotalCount; 
     Value = filter.Value; 
     visibility = filter.visibility; 
    } 

    private void DateSelection() 
    { 

    } 
} 

而且

public class MainFilterTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate FilterDropdownTemplate { get; set; } 

    protected override DataTemplate SelectTemplateCore(object selector) 
    { 
     if (selector == null) 
     { 
      throw new ArgumentNullException("Template is null"); 
     } 
     if (!(selector is FilterBase)) 
     { 
      throw new ArgumentException("This list can only be populated by a class that extends Filter."); 
     } 
     else 
     { 
      var filterType = selector as Filter; 
      switch (filterType.DisplayType) 
      { 
       case "date": 
        return FilterDropdownTemplate; 
       default: 
        return base.SelectTemplateCore(selector); 
      } 
     } 
    } 
} 

而且

public class Filter : FilterBase 
{ 
    private int _selectedCount; 
    private int _totalCount; 
    private Visibility _visibility; 

    public IEnumerable<Filter> Children 
    { 
     get; 
     set; 
    } 

    public int TotalCount 
    { 
     get 
     { 
      return _totalCount; 
     } 
     set 
     { 
      SetProperty(ref _totalCount, value); 
     } 
    } 

    public int SelectedCount 
    { 
     get 
     { 
      return _selectedCount; 
     } 
     set 
     { 
      SetProperty(ref _selectedCount, value); 
     } 
    } 

    public Visibility visibility 
    { 
     get 
     { 
      return _visibility; 
     } 
     set 
     { 
      SetProperty(ref _visibility, value); 
     } 

    } 

    public void InitializeAllChildren(IEnumerable<Filter> allFilters) 
    { 
     foreach (Filter item in allFilters) 
     { 
      item.Children = allFilters.GetAllChildrenFiltersForParentID(item.ID) as IEnumerable<Filter>; 
      if (item.Children == null) 
      { 
       item.TotalCount = 0; 
      } 
      else 
      { 
       item.TotalCount = item.Children.Count(); 
       item.SelectedCount = item.Children.Where(t => t.IsSelected.Value).Count(); 
      } 
     } 
     Children = allFilters.GetAllChildrenFiltersForParentID(ID); 
    } 
} 

而且

public class FilterBase : ViewModelBase 
{ 
    public int ID 
    { 
     get 
     { 

      return _id; 
     } 
     set 
     { 
      SetProperty(ref _id, value); 
     } 
    } 



    public string Value 
    { 
     get 
     { 
      return _value; 
     } 

     set 
     { 
      SetProperty(ref _value, value); 
     } 
    } 
    public string Column 
    { 
     get 
     { 
      return _column; 
     } 

     set 
     { 
      SetProperty(ref _column, value); 
     } 
    } 

    public int ParentId 
    { 
     get 
     { 
      return _parentId; 
     } 

     set 
     { 
      SetProperty(ref _parentId, value); 
     } 
    } 

    public string DisplayType 
    { 
     get 
     { 
      return _displayType; 
     } 

     set 
     { 
      SetProperty(ref _displayType, value); 
     } 
    } 
    public bool? IsSelected 
    { 
     get 
     { 
      return _isSelected; 
     } 

     set 
     { 
      SetProperty(ref _isSelected, value); 
     } 
    } 

    private int _id; 
    private string _value; 
    private string _column; 
    private int _parentId; 
    private string _displayType; 
    private bool? _isSelected; 
} 

和(BindableBase從Prism.Mvvm命名空間)

public class ViewModelBase : BindableBase, IDisposable 
{ 
    PropertyChangeActionHelper _propertyChangeActionHelper; 

    protected void RegisterPropertyChangeAction(Action action, params string[] monitoredProperties) 
    { 
     if (_propertyChangeActionHelper == null) 
     { 
      _propertyChangeActionHelper = new PropertyChangeActionHelper(this); 
     } 

     _propertyChangeActionHelper.RegisterPropertyChangeAction(action, monitoredProperties); 
    } 

    #region IDisposable Support 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (_propertyChangeActionHelper != null) 
      { 
       _propertyChangeActionHelper.Dispose(); 
       _propertyChangeActionHelper = null; 
      } 
     } 
    } 

    ~ViewModelBase() 
    { 
     // Do not change this code. Put cleanup code in Dispose(bool disposing) above. 
     Dispose(false); 
    } 

    // This code added to correctly implement the disposable pattern. 
    public void Dispose() 
    { 
     // Do not change this code. Put cleanup code in Dispose(bool disposing) above. 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
    #endregion 
} 
+0

它確實是一個構建錯誤?即一個致命的錯誤,阻止可執行文件的建立? WPF通常會發出非致命錯誤,這僅僅是因爲編輯器試圖評估設計時沒有設置的東西。在任何情況下,如果您提供[更好的代碼示例](https://stackoverflow.com/help/mcve),您可能會發現您獲得答案的運氣會更好(例如,您已經省略了兩個在XAML),如果您可以使用基本的Windows應用商店應用而不是通用的(並非每個人都已升級到Windows 10兼容的開發環境)來提供repro案例。 –

+0

是的,它阻止了建築物的代碼。我刪除了額外的模板並添加了填充列表及其繼承樹的類。 –

+0

關於'x:Bind'和'x:DataType':假設'templates'命名空間是聲明的並且'FilterDropdownDataTemplate'是該命名空間中的一個類型,您應該能夠定義DataTemplate的數據類型而不使用'x:Type':'' – andreask

回答

0

假設templates聲明命名空間和FilterDropdownDataTemplate是該命名空間中的一個類型,你應該能夠使用以下語法定義DataTemplate的數據類型,但不使用x:Type

<DataTemplate x:DataType="templates:FilterDropdownDataTemplate">