簡體   English   中英

XAML嵌套模板綁定

[英]XAML nested template binding

我有一個列表視圖,在這里我將多個數據模板綁定到一個DataTemplateSelector上。 但是,我無法構建我的項目,出現錯誤“對象引用未設置為對象的實例”。 我將問題縮小為組合框的數據綁定ItemsSource。 如果我注釋掉組合框,則將構建我的項目。 據我了解,Binding關鍵字在運行時求值,但這是編譯時錯誤。 我試圖通過換成x:Bind來解決該錯誤,因為它在編譯時求值,但隨后需要定義DataTemplate的類型。

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

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

這是我的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
}

假設聲明了templates名稱空間,並且FilterDropdownDataTemplate是該名稱空間中的一種類型,那么您應該能夠使用以下語法在沒有x:Type情況下定義DataTemplate的數據類型:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM