| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1770 人关注过本帖
标题:求 wpf 仿 win8 磁贴例子
只看楼主 加入收藏
伍则帝
Rank: 3Rank: 3
来 自:四川省南充市高坪区
等 级:论坛游民
威 望:6
帖 子:100
专家分:34
注 册:2013-3-16
结帖率:84%
收藏
 问题点数:0 回复次数:1 
求 wpf 仿 win8 磁贴例子
想做一个win磁贴界面,但wpf还未入门。求实例,求带!
2014-07-08 13:26
伍则帝
Rank: 3Rank: 3
来 自:四川省南充市高坪区
等 级:论坛游民
威 望:6
帖 子:100
专家分:34
注 册:2013-3-16
收藏
得分:0 
设计方案:整个界面主要分为两块:MetroStyle和MetroButton

MetroStyle设计如下:

MetroButton设计如下:

MetroButton的主要功能是显而易见的,其中主要实现了三个依赖属性:MetroBtnForeImage(绑定Image)、MetroBtnText(绑定Text)、MetroBtnUri(点击MetroButton后跳转Uri)。

实现
MetroButton的制作上参考了烤地瓜的系列教程中ImageButton的制作,只是在其基础上添加了需要的依赖属性和动画。

布局代码:(样式代码太多就不贴了)

<grid Name="layout"  RenderTransformOrigin="0.5,0.5" >
    </grid><grid .RenderTransform>
        <transformgroup>
            <scaletransform></scaletransform>
            <skewtransform></skewtransform>
            <rotatetransform></rotatetransform>
            <translatetransform></translatetransform>
        </transformgroup>
    </grid>
    <button x:Name="btnMetro"  
        HorizontalAlignment="Center"
        Style="{DynamicResource MetroButtonStyle}"
        VerticalAlignment="Center"
        Tag="{Binding MetroBtnText, ElementName=UserControl}" >
        <image Name="ForeImage"
            Source="{Binding MetroBtnForeImage, ElementName=UserControl}"  
            Stretch="Fill" Width="140" Height="140"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"></image>
     </button>
依赖属性定义:

/// <summary>
/// MetroButton.xaml 的交互逻辑
/// </summary>
public partial class MetroButton : UserControl
{
    public MetroButton()
    {
     
        this.InitializeComponent();
    }
    //按钮前景图
    public static readonly DependencyProperty MetroBtnForeImageProperty;
    //按钮文字
    public static readonly DependencyProperty MetroBtnTextProperty;
    //按钮绑定页面uri
    public static readonly DependencyProperty MetroBtnUriProperty;
 
    public ImageSource MetroBtnForeImage
    {
        get { return (ImageSource)GetValue(MetroBtnForeImageProperty); }
        set { SetValue(MetroBtnForeImageProperty, value); }
    }
 
    public string MetroBtnUri
    {
            get { return (string)GetValue(MetroBtnUriProperty); }
            set { SetValue(MetroBtnUriProperty, value); }
    }
 
    public string MetroBtnText
    {
        get { return (string)GetValue(MetroBtnTextProperty); }
        set { SetValue(MetroBtnTextProperty, value); }
    }
 
    static MetroButton()
    {
        var metadataImage = new FrameworkPropertyMetadata((ImageSource)null);
        var metadataText = new FrameworkPropertyMetadata((string)null);
        var metadataUri = new FrameworkPropertyMetadata((string)null);
           
        MetroBtnForeImageProperty = DependencyProperty.RegisterAttached("MetroBtnForeImage", typeof(ImageSource), typeof(MetroButton), metadataImage);
        MetroBtnTextProperty = DependencyProperty.RegisterAttached("MetroBtnText", typeof(string), typeof(MetroButton), metadataText);
        MetroBtnUriProperty = DependencyProperty.RegisterAttached("MetroBtnUri", typeof(string), typeof(MetroButton), metadataUri);
    }
}
MetroStyle中主要分为了2块:界面布局和页面跳转动画。

界面布局:(主要做的是针对1366*768分辨率的屏幕做的,如果需要适应各种分辨率还需修改)

<s:surfacescrollviewer x:Name="GridScrollViewer"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Width="1366"  Height="768"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Disabled"
PanningMode="HorizontalOnly">
    <grid x:Name="OptionGrid" RenderTransformOrigin="0.5,0.5"
        HorizontalAlignment="Left" VerticalAlignment="Top"
        Height="768" Width="auto" Background="#00000000" OpacityMask="Black" >
        </grid><grid .RowDefinitions >
            <rowdefinition Height="180"></rowdefinition>
            <rowdefinition Height="152"></rowdefinition>
            <rowdefinition Height="152"></rowdefinition>
            <rowdefinition Height="152"></rowdefinition>
            <rowdefinition Height="136"></rowdefinition>
        </grid>
        <grid .ColumnDefinitions >
            <columndefinition Width="100"></columndefinition>
            <columndefinition Width="152"></columndefinition>
        </grid>
        <textblock Text="开始" HorizontalAlignment="Center"
            VerticalAlignment="Center" Grid.Column="1" Grid.Row="0"
            FontSize="64" Foreground="White"></textblock>
   
</s:surfacescrollviewer>
跳转动画(布局):

<metro:loadanimationcontrol x:Name="LoadControl"
    Width="1366" Height="768"  Visibility="Hidden">
    <grid x:Name="LayoutRoot" RenderTransformOrigin="0.5,0.5">
        </grid><grid .RenderTransform>
            <transformgroup>
            <scaletransform></scaletransform>
            <skewtransform></skewtransform>
            <rotatetransform></rotatetransform>
            <translatetransform></translatetransform>
            </transformgroup>
        </grid>
        <rectangle Name="rectangle" Fill="#FF20B1C4"
            Stroke="Transparent" Width="480" Height="270">
            </rectangle><rectangle .RenderTransform>
                <transformgroup>
                    <scaletransform></scaletransform>
                    <skewtransform></skewtransform>
                    <rotatetransform></rotatetransform>
                    <translatetransform></translatetransform>
                </transformgroup>
            </rectangle>
        
        <stackpanel Width="auto" Height="auto"
            HorizontalAlignment="Center"
            VerticalAlignment="Center">
            <image Name="ForwardImage" HorizontalAlignment="Center"
                Height="206.4"  Stretch="Fill" VerticalAlignment="Center" Width="215"></image>
        </stackpanel>
   
</metro:loadanimationcontrol>
 
跳转动画(动画):

<storyboard x:Key="LoadAnimation" Completed="sb_Completed">
    <pointanimationusingkeyframes Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)"
        Storyboard.TargetName="rectangle">
        <easingpointkeyframe KeyTime="0" Value="0.5,0.5"></easingpointkeyframe>
        <easingpointkeyframe KeyTime="0:0:0.3" Value="0.5,0.5"></easingpointkeyframe>
    </pointanimationusingkeyframes>
    <doubleanimationusingkeyframes Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
        Storyboard.TargetName="rectangle">
        <easingdoublekeyframe KeyTime="0:0:0.3" Value="2.90"></easingdoublekeyframe>
    </doubleanimationusingkeyframes>
    <doubleanimationusingkeyframes Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
        Storyboard.TargetName="rectangle">
        <easingdoublekeyframe KeyTime="0:0:0.3" Value="2.90"></easingdoublekeyframe>
    </doubleanimationusingkeyframes>
    <doubleanimationusingkeyframes Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
        Storyboard.TargetName="rectangle">
        <easingdoublekeyframe KeyTime="0:0:0.6" Value="2.90"></easingdoublekeyframe>
    </doubleanimationusingkeyframes>
    <doubleanimationusingkeyframes Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
        Storyboard.TargetName="rectangle">
        <easingdoublekeyframe KeyTime="0:0:0.6" Value="2.90"></easingdoublekeyframe>
    </doubleanimationusingkeyframes>
    <doubleanimationusingkeyframes Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
        Storyboard.TargetName="LayoutRoot">
        <easingdoublekeyframe KeyTime="0" Value="-1">
            </easingdoublekeyframe><easingdoublekeyframe .EasingFunction>
                <cubicease EasingMode="EaseOut"></cubicease>
            </easingdoublekeyframe>
        
        <easingdoublekeyframe KeyTime="0:0:0.3" Value="1">
            </easingdoublekeyframe><easingdoublekeyframe .EasingFunction>
                <cubicease EasingMode="EaseOut"></cubicease>
            </easingdoublekeyframe>
        
    </doubleanimationusingkeyframes>
</storyboard>
跳转动画的实现主要是对一个Rectangle进行翻转并放大,且将MetroButton中的图片置于页面中心,动画播放完后触发Completed事件,执行跳转。

界面布局动态加载MetroButton的实现:

我在项目中添加了两个文件夹:View和Image。Image用于保存页面图标,而View中则保存着相应的页面文件,并且二者中的文件通过文件名一一对应(如:View/v1/Mail.xaml代表着一个页面,相应的在Image/v1下,应存在一个名为Mail.png或Mail.jpg等类型的文件与之对应),在这两个文件夹中还存在子文件夹,在界面加载时,每一个文件夹体现为一个块。

 /// <summary>
 /// MetroStyle.xaml 的交互逻辑
 /// </summary>
 public partial class MetroStyle : Page
 {
        private string uri;
        DirectoryInfo app = null;//页面目录  默认为Application/view
        DirectoryInfo img = null;//页面图标目录   默认为Application/Image
        string env;
 
  public MetroStyle()
 {
 this.InitializeComponent();
            env = Environment.CurrentDirectory.Replace("\\bin\\Debug", "");//获取程序根目录
            LoadAllApp();
 }
 
        /// <summary>
        /// 在主页面加载页面图标
        /// </summary>
        public void LoadAllApp()
        {
            defineGrid();
            int row = 1;
            int column = 1;
            int index = 0;
           
            img = new DirectoryInfo(env + "\\Image");
            for (int i = 0; i < img.GetDirectories().Length; i++)
            {
                index = 0;
               
                for (int j = 0; j < app.GetDirectories()[i].GetFiles().Length; j++)
                {
                    string tmpex = app.GetDirectories()[i].GetFiles()[j].Extension;
                    if (tmpex.Contains("xaml"))
                    {
                        if (row > 3 && j >0)
                            column += 1;
                        if (row > 3 || j == 0)
                        {
                            row = 1;
                        }
                        MetroButton mb = new MetroButton();
                        //设置页面uri
                        mb.MetroBtnUri = app.GetDirectories()[i].Name + "\\" + app.GetDirectories()[i].GetFiles()[j].Name;
                        //设置图片
                        mb.MetroBtnForeImage = (ImageSource)new ImageSourceConverter().ConvertFromString(img.GetDirectories()[i].GetFiles()[index].FullName);
                        //设置文字
                        mb.MetroBtnText = img.GetDirectories()[i].GetFiles()[index].Name.Split('.')[0];
                       
                        mb.SetValue(Grid.RowProperty, row);
                        mb.SetValue(Grid.ColumnProperty, column);
                        //添加点击事件
                        mb.PreviewMouseLeftButtonUp += MetroButton_MouseLeftButtonUp;
                        this.OptionGrid.Children.Add(mb);
                        row++;
                        index++;
                    }
                }
                column += 2;
            }
        }
        /// <summary>
        /// 计算Grid大小
        /// </summary>
        public void defineGrid()
        {
            app = new DirectoryInfo(env + "\\view");
            int sumOfApp = 0;
            int sumOfPart = app.GetDirectories().Length;
            int tmp = 0;
 
            foreach (DirectoryInfo di in app.GetDirectories())
            {
                sumOfApp = di.GetFiles().Length;
                int numOfColunm = sumOfApp /2 / 3 + (sumOfApp % 3 > 0 ? 1 : 0);
                if (tmp == 0)
                    numOfColunm -= 1;
                for (int i = 0; i < numOfColunm; i++)
                {
                    ColumnDefinition appColumn = new ColumnDefinition();
                    appColumn.Width = new GridLength(152);
                    this.OptionGrid.ColumnDefinitions.Add(appColumn);
                }
                ColumnDefinition spanColumn = new ColumnDefinition();
                spanColumn.Width = new GridLength(50);
                this.OptionGrid.ColumnDefinitions.Add(spanColumn);
                tmp++;
 
            }
        }
 
        /// <summary>
        /// /点击MetroButton事件
        ///
        /// <param name="sender"/>
        /// <param name="e"/>
        private void MetroButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            uri = (sender as MetroButton).MetroBtnUri;
            this.ForwardImage.Source = (sender as MetroButton).MetroBtnForeImage;
            SolidColorBrush rbrg = new SolidColorBrush(getBackgroudColor(this.ForwardImage));
            this.rectangle.Fill = rbrg;
            this.LoadControl.Visibility = Visibility.Visible;
            Storyboard sb = (Storyboard)this.FindResource("LoadAnimation");
            sb.Begin();
        }
        /// <summary>
        /// 获取图标的背景颜色
        /// </summary>
        /// <param name="img"/>
        /// <returns></returns>
        public System.Windows.Media.Color getBackgroudColor(System.Windows.Controls.Image img)
        {
            string path = img.Source.ToString().Replace("file:///","");
            Bitmap bmp = new Bitmap(path);
            byte a = bmp.GetPixel(1, 1).A;
            byte r = bmp.GetPixel(1, 1).R;
            byte g = bmp.GetPixel(1, 1).G;
            byte b = bmp.GetPixel(1, 1).B;
 
            System.Windows.Media.Color color = System.Windows.Media.Color.FromArgb(a, r, g, b);
            return color;
 
        }
        /// <summary>
        /// /动画完成后执行跳转
        /// </summary>
        /// <param name="sender"/>
        /// <param name="e"/>
        private void sb_Completed(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri(@"view\"+uri, UriKind.Relative));
        }
2014-07-08 13:53
快速回复:求 wpf 仿 win8 磁贴例子
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015752 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved