我使用自己的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不绑定。
答案 0 :(得分:1)
我查看了代码,看起来确实很好。
如果在OnItemsSourcePropertyChanged方法中设置断点,则可以看到DP ItemsSourceProperty绑定到EpisodeList,并且存储在属性ItemsSource中的获取IList的调用具有我们期望的值。< / p>
有什么证据表明EpisodeList没有绑定到ItemsSource?
如果问题是网格按钮没有显示,我不确定你是否已经显示了如何创建按钮控件的任何代码,可能问题就在那里,而不是在绑定中。
这是我编写的ControlTemplate的一个示例,它管理您在FourByTwoGrid类中定义的状态。您可以在XAML中添加以下内容以引用它。
<GridLayout:FourByTwoGrid x:Name="fourbytwogrid"
ItemsSource="{Binding EpisodeList}"
ItemTemplate="{StaticResource butemp}"
Template="{StaticResource FourByTwoGridTemplate}" />
这是ControlTemplate的定义。如果没有这个,您的代码无法知道如何在方法UpdateVisualState()中显示您引用的状态。
将其添加到CoreView XAML中的资源字典中:
<ControlTemplate x:Key="FourByTwoGridTemplate" TargetType="GridLayout:FourByTwoGrid">
<Grid>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="Button0States">
<vsm:VisualState x:Name="Button0Visible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Button0">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Button0NotVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Button0">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name="Button1States">
<vsm:VisualState x:Name="Button1Visible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Button1">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Button1NotVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Button1">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name="Button2States">
<vsm:VisualState x:Name="Button2Visible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Button2">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Button2NotVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Button2">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Name="Button0" Content="0" Visibility="Hidden" />
<Button Grid.Row="0" Grid.Column="1" Name="Button1" Content="1" Visibility="Hidden" />
<Button Grid.Row="1" Grid.Column="0" Name="Button2" Content="2" Visibility="Hidden" />
<Button Grid.Row="1" Grid.Column="1" Name="Button3" Content="3" Visibility="Hidden" />
<Button Grid.Row="2" Grid.Column="0" Name="Button4" Content="4" Visibility="Hidden" />
<Button Grid.Row="2" Grid.Column="1" Name="Button5" Content="5" Visibility="Hidden" />
<Button Grid.Row="3" Grid.Column="0" Name="Button6" Content="6" Visibility="Hidden" />
<Button Grid.Row="3" Grid.Column="1" Name="Button7" Content="7" Visibility="Hidden" />
</Grid>
</ControlTemplate>
答案 1 :(得分:0)
问题出现在ViewModel
。您正在尝试将ItemsSource
绑定到名为“EpisodeList”的属性。但是RaisePropertyChanged
指的是非约束成员“episodeList”。