0

我创建了自己的自定义控件,它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 不绑定。

4

2 回答 2

1

我查看了代码,它似乎绑定得很好。

如果在 OnItemsSourcePropertyChanged 方法中设置断点,您可以看到 DP ItemsSourceProperty 绑定到 EpisodeList,并且获取存储在属性 ItemsSource 中的 IList 的调用具有我们期望的值。

什么证据表明 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>

于 2012-09-20T17:39:51.883 回答
0

看起来问题出在ViewModel. 您正在尝试绑定ItemsSource到名为“EpisodeList”的属性。但RaisePropertyChanged指的是非绑定成员“episodeList”。

于 2012-09-12T19:43:59.030 回答