我创建了自己的自定义控件,它DependencyProperty
ItemsSource
根据绑定列表中提供的项目数量动态创建按钮。创建 XAML 时,我应该能够通过声明将列表绑定到我的自定义控件
ItemsSource="{Binding ListOfData}".
我似乎无法让它显示按钮或显示,数据是否没有正确绑定到列表?
[TemplateVisualState(GroupName = "Button0States", Name = "Button0Visible")]
[TemplateVisualState(GroupName = "Button0States", Name = "Button0NotVisible")]
[TemplateVisualState(GroupName = "Button1States", Name = "Button1Visible")]
[TemplateVisualState(GroupName = "Button1States", Name = "Button1NotVisible")]
[TemplateVisualState(GroupName = "Button2States", Name = "Button2Visible")]
[TemplateVisualState(GroupName = "Button2States", Name = "Button2NotVisible")]
[TemplateVisualState(GroupName = "Button3States", Name = "Button3Visible")]
[TemplateVisualState(GroupName = "Button3States", Name = "Button3NotVisible")]
[TemplateVisualState(GroupName = "Button4States", Name = "Button4Visible")]
[TemplateVisualState(GroupName = "Button4States", Name = "Button4NotVisible")]
[TemplateVisualState(GroupName = "Button5States", Name = "Button5Visible")]
[TemplateVisualState(GroupName = "Button5States", Name = "Button5NotVisible")]
[TemplateVisualState(GroupName = "Button6States", Name = "Button6Visible")]
[TemplateVisualState(GroupName = "Button6States", Name = "Button6NotVisible")]
[TemplateVisualState(GroupName = "Button7States", Name = "Button7Visible")]
[TemplateVisualState(GroupName = "Button7States", Name = "Button7NotVisible")]
[TemplatePart(Name = "btn0", Type = typeof(Control))]
[TemplatePart(Name = "btn7", Type = typeof(Control))]
[TemplatePart(Name = "btnMore", Type = typeof(Control))]
[TemplateVisualState(GroupName = "MoreButtonStates", Name = "MoreButtonVisible")]
[TemplateVisualState(GroupName = "MoreButtonStates", Name = "MoreButtonNotVisible")]
public class FourByTwoGrid : Control
{
public FourByTwoGrid()
{
this.DefaultStyleKey = typeof(FourByTwoGrid);
this.Loaded += new RoutedEventHandler(FourByTwoGrid_Loaded);
this.GotFocus += new RoutedEventHandler(FourByTwoGrid_GotFocus);
}
public IList ItemsSource
{
get { return GetValue(ItemsSourceProperty) as IList; }
set { Logger.Log("Value set"); SetValue(ItemsSourceProperty, value); }
}
/// <summary>
/// Identifies the ItemsSource dependency property.
/// </summary>
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register(
"ItemsSource",
typeof(IList),
typeof(FourByTwoGrid),
new PropertyMetadata(null, OnItemsSourcePropertyChanged));
/// <summary>
/// ItemsSourceProperty property changed handler.
/// </summary>
/// <param name="d">FourByTwoGrid that changed its ItemsSource.</param>
/// <param name="e">Event arguments.</param>
private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FourByTwoGrid source = d as FourByTwoGrid;
if (source != null)
{
source.AttemptToBuildGridUi();
}
}
#region public DataTemplate ItemTemplate
/// <summary>
/// Gets or sets an ItemTemplate to be used in the buttons.
/// </summary>
public DataTemplate ItemTemplate
{
get { return GetValue(ItemTemplateProperty) as DataTemplate; }
set { SetValue(ItemTemplateProperty, value); }
}
/// <summary>
/// Identifies the ItemTemplate dependency property.
/// </summary>
public static readonly DependencyProperty ItemTemplateProperty =
DependencyProperty.Register(
"ItemTemplate",
typeof(DataTemplate),
typeof(FourByTwoGrid),
new PropertyMetadata(null, OnItemTemplatePropertyChanged));
/// <summary>
/// ItemTemplateProperty property changed handler.
/// </summary>
/// <param name="d">FourByTwoGrid that changed its ItemTemplate.</param>
/// <param name="e">Event arguments.</param>
private static void OnItemTemplatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FourByTwoGrid source = d as FourByTwoGrid;
if (source != null)
{
source.AttemptToBuildGridUi();
}
}
/// <summary>
/// Update the visual state of buttons based on whether or not an item exists.
/// </summary>
private void UpdateVisualState()
{
// set buttons to visible if there's a corresponding item
var lastI = 0;
if (ItemsSource != null)
{
for (int i = 0; i < ItemsSource.Count && i < 8; i++)
{
lastI = i;
VisualStateManager.GoToState(this, "Button" + i + "Visible", false);
Logger.Log("Visible" + i);
}
lastI++;
}
// set buttons to nto visible for all buttons that don't have a corresponding item
for (int i = lastI; i < 8; i++)
{
}
if (ShouldMoreButtonBeVisible)
{
VisualStateManager.GoToState(this, "MoreButtonVisible", false);
}
else
{
VisualStateManager.GoToState(this, "MoreButtonNotVisible", false);
}
}
/// <summary>
/// Attempt to populate the UI based on control properties.
/// </summary>
private void AttemptToBuildGridUi()
{
UpdateVisualState();
UpdateItemsSourceBindings();
}
/// <summary>
/// It seems that the TemplateParent bindings aren't automatically updated.
/// We'll invoke Update on each of these.
/// </summary>
private void UpdateItemsSourceBindings()
{
if (ItemsSource == null)
return;
if ((ItemsSource.Count > 0) && !ItemsSource[0].Equals(Item0))
Item0 = ItemsSource[0];
if ((ItemsSource.Count > 1) && !ItemsSource[1].Equals(Item1))
Item1 = ItemsSource[1];
if ((ItemsSource.Count > 2) && !ItemsSource[2].Equals(Item2))
Item2 = ItemsSource[2];
if ((ItemsSource.Count > 3) && !ItemsSource[3].Equals(Item3))
Item3 = ItemsSource[3];
if ((ItemsSource.Count > 4) && !ItemsSource[4].Equals(Item4))
Item4 = ItemsSource[4];
if ((ItemsSource.Count > 5) && !ItemsSource[5].Equals(Item5))
Item5 = ItemsSource[5];
if ((ItemsSource.Count > 6) && !ItemsSource[6].Equals(Item6))
Item6 = ItemsSource[6];
if ((ItemsSource.Count > 7) && !ItemsSource[7].Equals(Item7))
Item7 = ItemsSource[7];
Logger.Log("Layout updated");
ItemsCountText = ItemsSource.Count.ToString(CultureInfo.InvariantCulture);
}
#region public object Item0
/// <summary>
/// Gets or sets item #0.
/// </summary>
public object Item0
{
get { return GetValue(Item0Property) as object; }
set { SetValue(Item0Property, value); }
}
/// <summary>
/// Identifies the Item0 dependency property.
/// </summary>
public static readonly DependencyProperty Item0Property =
DependencyProperty.Register(
"Item0",
typeof(object),
typeof(FourByTwoGrid),
new PropertyMetadata(null));
#endregion public object Item0
#region public object Item1
/// <summary>
/// Gets or sets item #1.
/// </summary>
public object Item1
{
get { return GetValue(Item1Property) as object; }
set { SetValue(Item1Property, value); }
}
/// <summary>
/// Identifies the Item1 dependency property.
/// </summary>
public static readonly DependencyProperty Item1Property =
DependencyProperty.Register(
"Item1",
typeof(object),
typeof(FourByTwoGrid),
new PropertyMetadata(null));
#endregion public object Item1
#region public object Item2
/// <summary>
/// Gets or sets item #2.
/// </summary>
public object Item2
{
get { return GetValue(Item2Property) as object; }
set { SetValue(Item2Property, value); }
}
/// <summary>
/// Identifies the Item2 dependency property.
/// </summary>
public static readonly DependencyProperty Item2Property =
DependencyProperty.Register(
"Item2",
typeof(object),
typeof(FourByTwoGrid),
new PropertyMetadata(null));
#endregion public object Item2
#region public object Item3
/// <summary>
/// Gets or sets item #3.
/// </summary>
public object Item3
{
get { return GetValue(Item3Property) as object; }
set { SetValue(Item3Property, value); }
}
/// <summary>
/// Identifies the Item3 dependency property.
/// </summary>
public static readonly DependencyProperty Item3Property =
DependencyProperty.Register(
"Item3",
typeof(object),
typeof(FourByTwoGrid),
new PropertyMetadata(null));
#endregion public object Item3
#region public object Item4
/// <summary>
/// Gets or sets item #4.
/// </summary>
public object Item4
{
get { return GetValue(Item4Property) as object; }
set { SetValue(Item4Property, value); }
}
/// <summary>
/// Identifies the Item4 dependency property.
/// </summary>
public static readonly DependencyProperty Item4Property =
DependencyProperty.Register(
"Item4",
typeof(object),
typeof(FourByTwoGrid),
new PropertyMetadata(null));
#endregion public object Item4
#region public object Item5
/// <summary>
/// Gets or sets item #5.
/// </summary>
public object Item5
{
get { return GetValue(Item5Property) as object; }
set { SetValue(Item5Property, value); }
}
/// <summary>
/// Identifies the Item5 dependency property.
/// </summary>
public static readonly DependencyProperty Item5Property =
DependencyProperty.Register(
"Item5",
typeof(object),
typeof(FourByTwoGrid),
new PropertyMetadata(null));
#endregion public object Item5
#region public object Item6
/// <summary>
/// Gets or sets item #6.
/// </summary>
public object Item6
{
get { return GetValue(Item6Property) as object; }
set { SetValue(Item6Property, value); }
}
/// <summary>
/// Identifies the Item6 dependency property.
/// </summary>
public static readonly DependencyProperty Item6Property =
DependencyProperty.Register(
"Item6",
typeof(object),
typeof(FourByTwoGrid),
new PropertyMetadata(null));
#endregion public object Item6
#region public object Item7
/// <summary>
/// Gets or sets item #7.
/// </summary>
public object Item7
{
get { return GetValue(Item7Property) as object; }
set { SetValue(Item7Property, value); }
}
/// <summary>
/// Identifies the Item7 dependency property.
/// </summary>
public static readonly DependencyProperty Item7Property =
DependencyProperty.Register(
"Item7",
typeof(object),
typeof(FourByTwoGrid),
new PropertyMetadata(null));
#endregion public object Item7
EpisodeList 是 SeriesViewModel 类中的 IList,我想将该列表绑定到我的 EpisodeGrid 控件。
public class SeriesViewModel : CoreViewModel
{
public IList episodeList = new ObservableCollection<Episode>
{
new Episode {image =""},
new Episode {image =""},
......
}
public IList EpisodeList
{
get {return this.episodeList;}
set
{
this.episodeList = value;
RaisePropertyChanged("EpisodeList");
}
}
}
<Core:CoreView
xmlns:Core="clr-namespace:AmebaTV_XBOXApplication.ViewModel"
x:Class="AmebaTV_XBOXApplication.UI.EpisodeGridView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:GridLayout="clr-namespace:AmebaTV_XBOXApplication.Controls.GridLayout"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xbox="clr-namespace:Microsoft.Xbox.Controls;assembly=Microsoft.Xbox"
mc:Ignorable="d"
d:DesignHeight="720" d:DesignWidth="1280"
Title="EpisodeGridView Page">
<Core:CoreView.ViewModel>
<Binding Path="SeriesViewModel" Source="{StaticResource viewModelLocator}"/>
</Core:CoreView.ViewModel>
<Core:CoreView.Resources>
<DataTemplate x:Key="button_template">
<Button Width="50" Height="50" >
<TextBlock Text="Button"/>
</Button>
</DataTemplate>
</Core:CoreView.Resources>
<Grid x:Name="LayoutRoot" Margin="0">
<GridLayout:FourByTwoGrid x:Name="fourbytwogrid"
ItemsSource="{Binding EpisodeList}"
ItemTemplate="{StaticResource button_template}"/>
</Grid>
</Core:CoreView>
我在上面缺少什么?它编译得很好,但在运行时 EpisodeList 不绑定。