歡迎您光臨本站 註冊首頁

Silverlight系列6 - UserControl的繼承

←手機掃碼閱讀     火星人 @ 2014-03-03 , reply:0

Silverlight系列6 - UserControl的繼承

在Silverlight中,UserControl的繼承一直是個麻煩事情,要繼承一個View(UserControl或者Page以及其他基類)比在ASP.NET中要麻煩一些。僅僅的在UserControl的類中定義繼承會存在各種各樣的問題,比如說要修改.g文件;更有不辭辛苦者竟然找到了用後台拼XAML的方式(網上一搜便知),對於有潔癖的程序員,這些解決方案都不是非常理想。

其實從sl3開始,ms就已經告訴我們如何正確的繼承UserControl等,只要你新建一個Page(注意,不是UserControl)就能看出端倪。

下面我舉個例子(代碼截取於我一時興起做的坦克大戰雛形)

首先我們有一個基類,這裡叫做BaseObject
using System.Windows;
using System.Windows.Controls;

namespace EternalTank {
    public class BaseObject : UserControl {
        double _x;
        public double X {
            get {
                _x = Canvas.GetLeft(this);
                return _x;
            }

            set {
                Canvas.SetLeft(this, value);
                _x = value;
            }
        }

        double _y;
        public double Y {
            get {
                _y = Canvas.GetTop(this);
                return _y;
            }

            set {
                Canvas.SetTop(this, value);
                _y = value;
            }
        }

        public ObjectDirection Direction { get; set; }

        /// <summary>
        /// 坦克的速度
        /// </summary>
        public double Speed {
            get { return (double)GetValue(SpeedProperty); }
            set { SetValue(SpeedProperty, value); }
        }

        public static readonly DependencyProperty SpeedProperty =
            DependencyProperty.Register("Speed", typeof(double), typeof(BaseObject), new PropertyMetadata(10d));
    }
}

這裡代碼的意義並不重要,但要記住它是基類並且繼承了UserControl,以方便其他的UserControl繼承它

接下來是一個它派生的類
namespace EternalTank.Assets {
    public partial class Brick : BaseObject {
        public Brick() {
            InitializeComponent();
        }
    }
}這列的Brick繼承了BaseObject,下面才是最關鍵的一步

這個Brick的XAML中我們做出如下定義
<my:BaseObject x:Class="EternalTank.Assets.Brick"
    xmlns:my="clr-namespace:EternalTank"
    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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <Grid x:Name="LayoutRoot" Background="White">
        <Rectangle Fill="Red" Width="13" Height="13"></Rectangle>
    </Grid>
</my:BaseObject>
看出來與一般的UserControl有什麼不同了嗎?

1.先要在XAML中聲明命名空間,對於這個例子則是

xmlns:my="clr-namespace:EternalTank"
2.然後讓它作為UserControl的跟元素,大概這個樣子

<my:BaseObject></my:BaseObject>運行一下看看,是不是一點問題沒有了?

小結
其實就如開篇中提到的一樣,這種方法已經廣泛的應用於Silverlight中了,比如navigation:Page中,只是鮮有人注意而已。

我個人覺得如果不是特別必要的話應當盡量避免這樣的繼承,畢竟它也一定程度的增加了我們的工作量和代碼理解難度。我的建議是靈活運用MVVM,我們的ViewModel難道不可以有一個共同的基類嗎:)

[火星人 ] Silverlight系列6 - UserControl的繼承已經有632次圍觀

http://coctec.com/docs/service/show-post-2631.html