天天看點

silverlight 自定義控件基礎篇(仿淘寶評論星級控件)

首先說說今天的控件能幹什麼?

1,仿淘寶的評論星級控件,滑鼠滑過星星,會變亮。

2,可以用來,展示某一類對象的狀态,或者統計資訊,比如說,某一類對象,有1~10不同的狀态,10為滿狀态,那麼該控件就能根據該對象的狀态顯示。

顯示方法(狀态為1的 亮一顆星,灰色的9顆星,狀态為2的 亮2顆,灰色的8顆,以此類推)

該控件的屬性

<my:StarsControl Number="6" Stars="{Binding Num}" IsComment="True"  Margin="5" ClickMe="StarsControl_ClickMe" MoveMe="StarsControl_MoveMe" ></my:StarsControl>
                     
           
1,Number,要顯示的總星數量,比如6,總共顯示6顆星(如果用作評論星級,代表滿級6星) 2,Stars,該對象的狀态,也就是将會亮多少顆星,其他的星(灰色) 3,IsComment,表示該控件是否能滑鼠滑過,更改星的狀态。true表示更改,false表示隻用來展示,不更改 事件 ClickMe,相當于每顆星星的點選事件 MoveMe,相當于每顆星星滑鼠移動事件 StarsControl的XAML
<UserControl x:Class="TestDemo.StarsControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="800" d:DesignWidth="300">
    <!--将每個StankPanel做為容器,将星星添加進來-->
     <StackPanel Orientation="Horizontal" x:Name="item" Loaded="item_Loaded" >

    </StackPanel>

</UserControl>
           
後置代碼.cs
public partial class StarsControl : UserControl//評論星級,或顯示信譽度
    {
        public StarsControl()
        {
            InitializeComponent();
        }

        //定義要顯示的星星個數,預設5
        public static readonly DependencyProperty NumberProperty = DependencyProperty.Register("Number", typeof(int), typeof(StarsControl), new PropertyMetadata(5,new PropertyChangedCallback(NumberPropertyChanged)));


        public int Number
        {
            get { return (int)GetValue(NumberProperty); }
            set { SetValue(NumberProperty, value); }
        }
        public static void NumberPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            StarsControl starts = (StarsControl)obj;
            starts.Number = (int)args.NewValue;
        }


        //定義是用來顯示使用者信譽度,還是評星級的
        public static readonly DependencyProperty IsCommentProperty = DependencyProperty.Register("IsComment", typeof(bool), typeof(StarsControl), new PropertyMetadata(true, new PropertyChangedCallback(IsCommentPropertyChanged)));

         public bool  IsComment
        {
            get { return (bool)GetValue(IsCommentProperty); }
            set { SetValue(IsCommentProperty, value); }
        }
        public static void IsCommentPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            StarsControl starts = (StarsControl)obj;
            starts.IsComment = (bool)args.NewValue;
        }

        //該使用者信譽度,總的信譽度是Number,預設亮4顆
        public static readonly DependencyProperty StarsProperty = DependencyProperty.Register("Stars", typeof(int), typeof(StarsControl), new PropertyMetadata(new PropertyChangedCallback(StarsPropertyChanged)));


        public int Stars
        {
            get { return (int)GetValue(StarsProperty); }
            set { SetValue(StarsProperty, value); }
        }

        public static void StarsPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            StarsControl test = (StarsControl)obj;
            string img = "/TestDemo;component/images/1.png";//亮的星星圖檔
            string img1 = "/TestDemo;component/images/0.png";//不亮的星星圖檔
         
            if ((int)args.NewValue >= test.Number)//判斷該使用者是的應該亮多少顆星
            {
                for (int i = 0; i < test.Number; i++)
                {
                    test.item.Children.Add(new Image() { Source = new BitmapImage(new Uri(img, UriKind.RelativeOrAbsolute)), Cursor = Cursors.Hand, ToolTip = new ToolTip() { Content = i + 1 } });
                }
            }
            else
            {
                int num = test.Number - (int)args.NewValue; //該使用者沒有達到滿信譽,則算出不亮的星星有幾顆
                int i;
                for (i = 0; i < (int)args.NewValue; i++)
                {
                    test.item.Children.Add(new Image() { Source = new BitmapImage(new Uri(img, UriKind.RelativeOrAbsolute)), Cursor = Cursors.Hand,ToolTip = new ToolTip() { Content=i+1 }});
                    
                }
              for (int j = 0; j < num; j++) //将不亮的星星加入StankPanel
                {
                    test.item.Children.Add(new Image() { Source = new BitmapImage(new Uri(img1, UriKind.RelativeOrAbsolute)), Cursor = Cursors.Hand, ToolTip = new ToolTip() { Content=i+j+1 } });

                }
            
            }
        }

        public Point InP;
        public Point OutP;
       
        private void item_Loaded(object sender, RoutedEventArgs e)
        {
            foreach (var v in ((StackPanel)sender).Children)//給所有的星星注冊事件MouseMove,MouseLeave,MouseEnter
            {
                ((Image)v).MouseMove += new MouseEventHandler(StarsControl_MouseMove);
                ((Image)v).MouseLeave += new MouseEventHandler(StarsControl_MouseLeave);
                ((Image)v).MouseEnter += new MouseEventHandler(StarsControl_MouseEnter);
                ((Image)v).MouseLeftButtonDown += new MouseButtonEventHandler(StarsControl_MouseLeftButtonDown);//給每個星星注冊一個MouseLeftButtonDown事件

            }
        }

        public delegate void Click(object sender, MouseButtonEventArgs e);
        public event Click ClickMe; //定義ClickMe事件,在調用此控件時,可以用該事件操作單個星星
        void StarsControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ClickMe(sender, e);
        }

        int result = 0;//記錄滑鼠是不是第一進入控件
        void StarsControl_MouseEnter(object sender, MouseEventArgs e)
        {
            if (result == 0)//
            {
                InP.X = e.GetPosition((Image)sender).X + 10;//第一次,擷取目前坐标将x+10
            }
            else {
                InP = e.GetPosition((Image)sender);//不是第一次 則就擷取目前坐标
                result = 1;
            }
           
        }

        void StarsControl_MouseLeave(object sender, MouseEventArgs e)
        {
            if (result == 0)
            {
                OutP.X = e.GetPosition((Image)sender).X  -10;//第一次,擷取目前坐标将x-10
            }
            else
            {
                OutP = e.GetPosition((Image)sender);//不是第一次 則就擷取目前坐标
                result = 1;
            };
        }
        public delegate void Move(object sender, MouseEventArgs e);
        public event Move MoveMe; //定義移動事件(調用該控件,如果要在滑鼠移動到每個星上更改對象的時候用)

        //為什麼第一次進去和離開要加10和減10,是因為如果一開始 将滑鼠移到最後一顆星上,在下面的判斷中是相當的,就不會産生變化
        void StarsControl_MouseMove(object sender, MouseEventArgs e)
        {
            MoveMe(sender, e);
            if (((bool)GetValue(IsCommentProperty))==true)//如果是用作評論星級的
            {
                string img = "/TestDemo;component/images/1.png";
                string img1 = "/TestDemo;component/images/0.png";


                if (InP.X < OutP.X) //如果滑鼠進入時的坐标小于出去時的坐标,就以為着滑鼠在從左向右移動,将所有移過的星星變亮(加載亮星星的路徑)
                {
                    ((Image)sender).Source = new BitmapImage(new Uri(img, UriKind.RelativeOrAbsolute));

                }
                else
                {
                    //從右向左在移動,星星變灰
                    ((Image)sender).Source = new BitmapImage(new Uri(img1, UriKind.RelativeOrAbsolute));
                }
                //第一顆星星永遠亮着
                ((Image)item.Children[0]).Source = new BitmapImage(new Uri(img, UriKind.RelativeOrAbsolute));

            }
        }
    }
           
以上StarsControl控件已經Ok,下面調用 xaml
<StackPanel  Name="stackPanel1"   >
        <ItemsControl  x:Name="Item">

            <ItemsControl.Template>
                <ControlTemplate TargetType="ItemsControl">
                    <Border BorderBrush="Aqua" BorderThickness="1" CornerRadius="15">
                        <ItemsPresenter/>
                    </Border>
                </ControlTemplate>
            </ItemsControl.Template>

            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                   <StackPanel Orientation="Horizontal" >
                        <TextBlock  Text="{Binding Name}" Margin="10"></TextBlock>
                        <my:StarsControl x:Name="starts" Number="6" Stars="{Binding Num}" IsComment="True"  Margin="5" ClickMe="StarsControl_ClickMe" MoveMe="StarsControl_MoveMe" ></my:StarsControl>
                        <TextBlock  Text="信譽度" Margin="10"></TextBlock>
                        <TextBlock  Text="{Binding Num}" Margin="10"></TextBlock>
                    </StackPanel>
                 </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

      
    </StackPanel>
           
後置代碼綁定
public class person 
    
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private int num;

        public int Num
        {
            get { return num; }
            set { num = value; }
        }
    }
           
List<person> list = new List<person>();
            list.Add(new person() { Name = "Jack", Num = 2 });
            list.Add(new person() { Name = "Jack", Num = 3 });
            list.Add(new person() { Name = "Jack", Num = 4 });
            list.Add(new person() { Name = "Jack", Num = 5 });
            list.Add(new person() { Name = "Jack", Num = 6 });
            list.Add(new person() { Name = "Jack", Num = 7 });

            Item.ItemsSource = list;
           
我是做了一個多條資料的綁定,當然可以直接指派
<my:StarsControl x:Name="starts" Number="6" Stars="5" IsComment="True"  Margin="5" ></my:StarsControl>
           
好了,看看效果 總共顯示6顆星,對象的狀态為2,3,4,5,6,7 和直接指派的5,星都是可以更改的 因為IsComment為True嘛, 還有兩個事件
private void StarsControl_ClickMe(object sender, MouseButtonEventArgs e)
        {
            MessageBox.Show(((person)((Image)sender).DataContext).Name);  
        }

        private void StarsControl_MoveMe(object sender, MouseEventArgs e)
        {
            MessageBox.Show(((person)((Image)sender).DataContext).Name);  
        } 
           
silverlight 自定義控件基礎篇(仿淘寶評論星級控件)
加載沒錯,jack的Num是2,3,4,5,6,7,
silverlight 自定義控件基礎篇(仿淘寶評論星級控件)
上下兩張圖檔的星是不是不一樣了,這就是IsComment屬性為True 從左向右滑過灰色圖檔變亮,從右向左滑過時,變灰的效果
silverlight 自定義控件基礎篇(仿淘寶評論星級控件)
這個是ClickMe事件,點選星星時,彈出目前對象的名字 在看IsComment設為false,隻展示不能改變星星的狀态
silverlight 自定義控件基礎篇(仿淘寶評論星級控件)
我滑鼠在6的位置 星星沒有變亮... 還有個定義事件應該判斷
public delegate void Click(object sender, MouseButtonEventArgs e);
        public event Click ClickMe; //定義ClickMe事件,在調用此控件時,可以用該事件操作單個星星
        void StarsControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (ClickMe != null)
            {
                ClickMe(sender, e);
            }
        }
           
MoveMe也一樣.............. 昨天本來做了一個動畫的按鈕,有點醜,放上去,又删掉了..... 周末了,大家周末玩的開心..............................................