从XAML实例化UIElement

时间:2018-11-06 00:12:33

标签: c# wpf xaml custom-controls

我想要达到的目标听起来并不像火箭科学。我要创建的是一个自定义控件,我可以直接从XAML向其中传递UIElements项列表,以便每个元素可以不同并嵌入不同的对象(网格/文本框/面板等)。

这是我要使用的xaml代码:

    <wpf:TileListDoubleItem>
        <wpf:TileListDoubleItem.FrontItem>
            <Grid>
                <TextBlock FontFamily="Calibri,Verdana" FontSize="16" FontWeight="Bold" Foreground="White" Text="Hello"></TextBlock>
            </Grid>
        </wpf:TileListDoubleItem.FrontItem>
        <wpf:TileListDoubleItem.BackItem>
            <Grid>
                <TextBlock FontFamily="Calibri,Verdana" FontSize="16" FontWeight="Bold" Foreground="White" Text="World"></TextBlock>
            </Grid>                                 
        </wpf:TileListDoubleItem.BackItem>
    </wpf:TileListDoubleItem>

这是我的自定义控制代码:

    public partial class TileListDoubleItem : UserControl, INotifyPropertyChanged
    {
        private bool _flipped;
        internal bool CanFlip { get { return true; } }

        private bool flipped
        {
            get {
                return this._flipped;
            }
            set {
                this._flipped = value;
                DisplayItem = this._flipped ? BackItem : FrontItem;
            }
        }

        public ObservableCollection<TileSide> Sides { get; set; }
        public ICommand FlipCommand;

        public TileListDoubleItem()
        {
            InitializeComponent();
            FlipCommand = new FlipCommand(this);
            flipped = false;
        }

        private UIElement displayItem { get; set; }
        public UIElement DisplayItem
        {
            get { return this.displayItem; }
            set {
                if (this.displayItem != value)
                {
                    this.displayItem = value;
                    OnPropertyChanged("DisplayItem");
                }
            }
        }

        public void Flip()
        {
            try
            {
                flipped = !flipped;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public UIElement FrontItem
        {
            get { return (UIElement)GetValue(FrontItemProperty); }
            set { SetValue(FrontItemProperty, value); }
        }

        public static readonly DependencyProperty FrontItemProperty =
        DependencyProperty.Register("FrontItem", typeof(UIElement), typeof(TileListDoubleItem), new UIPropertyMetadata(null));


        public UIElement BackItem
        {
            get { return (UIElement)GetValue(BackItemProperty); }
            set { SetValue(BackItemProperty, value); }
        }

        public static readonly DependencyProperty BackItemProperty =
        DependencyProperty.Register("BackItem", typeof(UIElement), typeof(TileListDoubleItem), new UIPropertyMetadata(null));

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

运行此命令时,我的FrontItem和BackItem都等于null,并且从不设置为UIElement(在此示例中为Grid)。 我想我所缺少的对于某些人来说应该非常明显。

在此先感谢任何人的帮助。

1 个答案:

答案 0 :(得分:0)

您的属性已按预期设置。例如,可以通过创建两个绑定到控件属性的TextBlocks来确认这一点:

<wpf:TileListDoubleItem x:Name="control">
    <wpf:TileListDoubleItem.FrontItem>
        <Grid>
            <TextBlock FontFamily="Calibri,Verdana" FontSize="16" FontWeight="Bold" Foreground="White" Text="Hello"></TextBlock>
        </Grid>
    </wpf:TileListDoubleItem.FrontItem>
    <wpf:TileListDoubleItem.BackItem>
        <Grid>
            <TextBlock FontFamily="Calibri,Verdana" FontSize="16" FontWeight="Bold" Foreground="White" Text="World"></TextBlock>
        </Grid>
    </wpf:TileListDoubleItem.BackItem>
</wpf:TileListDoubleItem>

<TextBlock Text="{Binding FrontItem.Children[0].Text, ElementName=control}" />
<TextBlock Text="{Binding BackItem.Children[0].Text, ElementName=control}" />

很显然,TileListDoubleItem的构造函数返回时将不会设置属性。 XAML解析器需要实例化该对象,然后才能设置其任何属性,就像您自己创建一个类的实例一样。