Silverlight Telerik控件学习:TreeView数据绑定并初始化选中状态、PanelBar的Accordion效果、TabPanel、Frame基本使用

实际开发中控件的数据源肯定是动态绑定的,不可能在xaml里写死item项。既然要绑定,就先来几个实体类:

上面是类图,各类的代码如下:

 BusinessBaseObject

using System.ComponentModel;
namespace BusinessObject
{
    public class BusinessBaseObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 属性改变时触发事件
        /// </summary>
        /// <param name="propertyName">Property that changed.</param>
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

SelectedItemBase

using System.Collections.ObjectModel;
using System.Windows.Markup;
namespace BusinessObject
{
    [ContentProperty("Children")]//指示Children属性是 XAML 的Content内容属性
    public class SelectedItemBase:BusinessBaseObject
    {
        public SelectedItemBase() 
        {
            Children = new Collection<SelectedItemBase>();
            IsSelected = true;
        }

        /// <summary>
        /// 得到下级元素容器
        /// </summary>
        public Collection<SelectedItemBase> Children { get; private set; }

        /// <summary>
        /// 是否有子项
        /// </summary>
        public bool HasChild
        {
            get
            {
                return Children.Count > 0;
            }
        }

        /// <summary>
        /// 是否选中
        /// </summary>
        private bool? _isSelected;

        /// <summary>
        /// 是否被选中
        /// </summary>
        public bool? IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                if (value != _isSelected)
                {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");
                }
            }
        }
    }
}

NodeItem 主要用于treeview中的节点数据展示

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Markup;

namespace BusinessObject
{
    /// <summary>
    /// 地区数据项
    /// </summary>
    public class NodeItem : SelectedItemBase
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public NodeItem()
        {
            Text = "";
            Value = "";
            Description = "";
            ImageUri = "/Common.Silverlight.Resource;component/img/Book.png";
        }

        /// <summary>
        /// 节点文本
        /// </summary>
        public string Text { get; set; }

        /// <summary>
        /// 节点值
        /// </summary>
        public string Value { set; get; }

        /// <summary>
        /// 节点描述
        /// </summary>
        public string Description { get; set; }     

        /// <summary>
        /// 节点图象
        /// </summary>
        public string ImageUri { get; set; }       

        
    }
}

MenuItem 主要用于菜单项展示

namespace BusinessObject
{
    public class MenuItem:NodeItem
    {
        public MenuItem() 
        {
            NavigateUri = "";
            ImageUri = "/Common.Silverlight.Resource;component/img/Book_Open.png";
        }

        /// <summary>
        /// 菜单点击后的链接地址
        /// </summary>
        public string NavigateUri { set; get; }
    }
}

SampleData生成示例数据集合

using System.Collections.ObjectModel;

namespace BusinessObject
{
    public class SampleData
    {
        private static ObservableCollection<NodeItem> _samplePlaceItemCollection;
        private static ObservableCollection<MenuItem> _sampleMenuItemCollection;

        public SampleData() { }

        static SampleData()
        {
            #region 地区演示数据
            _samplePlaceItemCollection = new ObservableCollection<NodeItem>();

            NodeItem ShangHai = new NodeItem() { Text = "上海市", IsSelected = false, ImageUri = "/Common.Silverlight.Resource;component/img/Home.png" };
            ShangHai.Children.Add(new NodeItem() { Text = "黄浦区", IsSelected = false });
            ShangHai.Children.Add(new NodeItem() { Text = "闵行区", IsSelected = false });
            ShangHai.Children.Add(new NodeItem() { Text = "徐汇区", IsSelected = false });

            NodeItem HuBei = new NodeItem() { Text = "湖北省", IsSelected = null, ImageUri = "/Common.Silverlight.Resource;component/img/Book_Open.png" };
            NodeItem WuHan = new NodeItem() { Text = "武汉市", ImageUri = "/Common.Silverlight.Resource;component/img/MSN.png" };
            WuHan.Children.Add(new NodeItem() { Text = "汉口区" });
            WuHan.Children.Add(new NodeItem() { Text = "汉阳区" });
            WuHan.Children.Add(new NodeItem() { Text = "武昌区", IsSelected = false, ImageUri = "/Common.Silverlight.Resource;component/img/Computer.png" });
            HuBei.Children.Add(WuHan);

            HuBei.Children.Add(new NodeItem() { Text = "孝感市" });


            _samplePlaceItemCollection.Add(ShangHai);
            _samplePlaceItemCollection.Add(HuBei);
            #endregion


            #region
            _sampleMenuItemCollection = new ObservableCollection<MenuItem>();
            MenuItem itemBasic = new MenuItem() { Text = "基础数据", IsSelected = true, ImageUri = "/Common.Silverlight.Resource;component/img/Computer.png" };
            itemBasic.Children.Add(new MenuItem() { Text = "部门管理", NavigateUri="Basic/Department.xap" });
            itemBasic.Children.Add(new MenuItem() { Text = "员工管理", NavigateUri="Basic/Employee.xap"  });
            itemBasic.Children.Add(new MenuItem() { Text = "menu001", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemBasic.Children.Add(new MenuItem() { Text = "menu002", NavigateUri = "Plan/FFM.xap" });
            itemBasic.Children.Add(new MenuItem() { Text = "menu003", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemBasic.Children.Add(new MenuItem() { Text = "menu004", NavigateUri = "Plan/FFM.xap" });
            itemBasic.Children.Add(new MenuItem() { Text = "menu005", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemBasic.Children.Add(new MenuItem() { Text = "menu006", NavigateUri = "Plan/FFM.xap" });
            itemBasic.Children.Add(new MenuItem() { Text = "menu007", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemBasic.Children.Add(new MenuItem() { Text = "menu008", NavigateUri = "Plan/FFM.xap" });


            MenuItem itemMsg = new MenuItem() { Text = "报文管理", IsSelected=false, ImageUri = "/Common.Silverlight.Resource;component/img/Home.png" };
            itemMsg.Children.Add(new MenuItem() { Text = "FFM报文计划", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemMsg.Children.Add(new MenuItem() { Text = "FSU报文计划", NavigateUri = "Plan/FFM.xap" });
            itemMsg.Children.Add(new MenuItem() { Text = "menu001", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemMsg.Children.Add(new MenuItem() { Text = "menu002", NavigateUri = "Plan/FFM.xap" });
            itemMsg.Children.Add(new MenuItem() { Text = "menu003", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemMsg.Children.Add(new MenuItem() { Text = "menu004", NavigateUri = "Plan/FFM.xap" });
            itemMsg.Children.Add(new MenuItem() { Text = "menu005", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemMsg.Children.Add(new MenuItem() { Text = "menu006", NavigateUri = "Plan/FFM.xap" });
            itemMsg.Children.Add(new MenuItem() { Text = "menu007", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemMsg.Children.Add(new MenuItem() { Text = "menu008", NavigateUri = "Plan/FFM.xap" });


            MenuItem itemOther = new MenuItem() { Text = "系统管理", IsSelected=false, ImageUri = "/Common.Silverlight.Resource;component/img/MSN.png" };
            itemOther.Children.Add(new MenuItem() { Text = "系统日志", NavigateUri = "Event/FFM.xap" });
            itemOther.Children.Add(new MenuItem() { Text = "退出登录", NavigateUri = "Plan/MSN.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemOther.Children.Add(new MenuItem() { Text = "menu001", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemOther.Children.Add(new MenuItem() { Text = "menu002", NavigateUri = "Plan/FFM.xap" });
            itemOther.Children.Add(new MenuItem() { Text = "menu003", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemOther.Children.Add(new MenuItem() { Text = "menu004", NavigateUri = "Plan/FFM.xap" });
            itemOther.Children.Add(new MenuItem() { Text = "menu005", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemOther.Children.Add(new MenuItem() { Text = "menu006", NavigateUri = "Plan/FFM.xap" });
            itemOther.Children.Add(new MenuItem() { Text = "menu007", NavigateUri = "Plan/FFM.xap", ImageUri = "/Common.Silverlight.Resource;component/img/Book.png" });
            itemOther.Children.Add(new MenuItem() { Text = "menu008", NavigateUri = "Plan/FFM.xap" });

            _sampleMenuItemCollection.Add(itemBasic);
            _sampleMenuItemCollection.Add(itemMsg);
            _sampleMenuItemCollection.Add(itemOther);
            #endregion
        }

        public static ObservableCollection<NodeItem> SamplePlaceItemCollection
        {
            get { return _samplePlaceItemCollection; }
        }

        public static ObservableCollection<MenuItem> SampleMenuItemCollection 
        {
            get { return _sampleMenuItemCollection; }
        }
    }
}

TreeView、ContextMenu

为了将NoteItem中的IsSelected属性在绑定时自动转换成CheckBox的CheckState,需要写一个转换器

using System;
using System.Windows.Automation;
using System.Windows.Data;

namespace Common.Silverlight
{
    public class BooleanToCheckStateConvertor : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool? isSelected = (bool?)value;
            ToggleState result = ToggleState.Off;

            if (isSelected.HasValue == false) 
            {
                result = ToggleState.Indeterminate;
            }
            else if (isSelected.Value) 
            {
                result = ToggleState.On;
            }
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            ToggleState state = (ToggleState)value;

            bool? result = null;

            switch (state)
            {
                case ToggleState.Indeterminate:
                    result = null;
                    break;
                case ToggleState.Off:
                    result = false;
                    break;
                case ToggleState.On:
                    result = true;
                    break;
                default:
                    break;
            }

            return result;
        }
    }
}

然后需要定义数据模板,如果需要右键弹出菜单,也一并加在里面

<UserControl x:Class="Telerik.Sample.TreeView"
    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" 
    xmlns:model="clr-namespace:BusinessObject;assembly=BusinessObject"
    xmlns:common="clr-namespace:Common.Silverlight;assembly=Common.Silverlight"   
    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">

    <Grid x:Name="LayoutRoot" Background="White">

        <Grid.Resources>

            <telerik:ContainerBindingCollection x:Name="BindingsCollection">
                <!--用于将节点的选中状态,与数据项的IsSelected绑定-->
                <telerik:ContainerBinding PropertyName="CheckState" Binding="{Binding IsSelected,Converter={StaticResource BooleanToCheckStateConvertor}, Mode=TwoWay}" />
                <!--将节点图象与数据项的ImageUri绑定-->
                <telerik:ContainerBinding PropertyName="DefaultImageSrc" Binding="{Binding ImageUri}" />
            </telerik:ContainerBindingCollection>


            <!--数据节点模板-->
            <DataTemplate x:Key="NodeTemplate" telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
                <TextBlock Text="{Binding Text}" />
            </DataTemplate>

            <!--子节点模板-->
            <telerik:HierarchicalDataTemplate x:Key="ChildTemplate" ItemTemplate="{StaticResource NodeTemplate}"
          ItemsSource="{Binding Children}" telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
                <TextBlock Text="{Binding Text}" />
            </telerik:HierarchicalDataTemplate>

            <!--父节点模板-->
            <telerik:HierarchicalDataTemplate x:Key="ParentTemplate" ItemTemplate="{StaticResource ChildTemplate}"
          ItemsSource="{Binding Children}"  telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
                <TextBlock Text="{Binding Text}" />
            </telerik:HierarchicalDataTemplate>
        </Grid.Resources>

        <telerik:RadTreeView
      ItemsSource="{Binding Source={StaticResource SampleDataSource}, Path=SamplePlaceItemCollection}"
      ItemTemplate="{StaticResource ParentTemplate}" SelectionMode="Extended" IsLineEnabled="True" ItemsOptionListType="CheckList"  IsOptionElementsEnabled="True" IsRootLinesEnabled="True" IsTriStateMode="True" Margin="10">
            <telerik:RadTreeView.ItemContainerStyle>
                <Style TargetType="telerik:RadTreeViewItem">
                    <!--默认全展开-->
                    <Setter Property="IsExpanded" Value="True"/>
                </Style>
            </telerik:RadTreeView.ItemContainerStyle>

            <!--右键弹出菜单-->
            <telerik:RadContextMenu.ContextMenu>
                <telerik:RadContextMenu x:Name="ContextMenu1" ItemClick="ContextMenuClick"
                        Opened="ContextMenuOpened">
                    <telerik:RadMenuItem Header="添加" Tag="Add" />
                    <telerik:RadMenuItem Header="删除" Tag="Delete" />
                    <telerik:RadMenuItem Header="修改" Tag="Edit" />
                    <telerik:RadMenuItem IsSeparator="True" />
                    <telerik:RadMenuItem Header="设置菜单权限" Tag="MenuRight" />
                    <telerik:RadMenuItem Header="设置数据范围" Tag="DataRange" />
                </telerik:RadContextMenu>
            </telerik:RadContextMenu.ContextMenu>

        </telerik:RadTreeView>



    </Grid>
</UserControl>

这里面用到了几个资源,定义在全局App.Xaml里

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             x:Class="Telerik.App"
             xmlns:model ="clr-namespace:BusinessObject;assembly=BusinessObject"
             xmlns:common ="clr-namespace:Common.Silverlight;assembly=Common.Silverlight"
             >
    <Application.Resources>        
        <!--示例数据源-->
        <model:SampleData x:Key="SampleDataSource"></model:SampleData>     
        <!--转换器:用于bool?转换成CheckBox的三种选中状态-->
        <common:BooleanToCheckStateConvertor x:Key="BooleanToCheckStateConvertor"></common:BooleanToCheckStateConvertor>
    </Application.Resources>
</Application>

右键弹出菜单点击后,我们需要知道是在哪个节点上弹出的,以及我们选择了哪个菜单项,需要一些后端处理代码

using System.Windows;
using System.Windows.Controls;
using BusinessObject;
using Telerik.Windows.Controls;

namespace Telerik.Sample
{
    public partial class TreeView : UserControl
    {
        NodeItem selectedNodeItem = null;

        public TreeView()
        {
            InitializeComponent();

            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            //this.RadTreeView1.ItemsSource = SampleData.SamplePlaceItemCollection;
        }

        /// <summary>
        /// 菜单弹出后,点击具体菜单项时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContextMenuClick(object sender, Windows.RadRoutedEventArgs e)
        {
            var origin_src = e.OriginalSource as RadMenuItem;           
           
            //反馈操作结果
            DialogParameters pars = new DialogParameters();            
            pars.Header = "信息";
            pars.Content = string.Format("你选择的菜单是:\n{0},{1}\n\n当前节点为:{2}\n{3}", origin_src.Header.ToString(), origin_src.Tag.ToString(), selectedNodeItem.Text,selectedNodeItem.ImageUri);
            RadWindow.Alert(pars);

            selectedNodeItem = null;
        }

        /// <summary>
        /// 菜单弹出时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContextMenuOpened(object sender, RoutedEventArgs e)
        {
            RadTreeViewItem item = this.ContextMenu1.GetClickedElement<RadTreeViewItem>();
            if (item != null) 
            {
                selectedNodeItem = item.DataContext as NodeItem;
            }

        }
    }
}

 运行效果图:

选择一个弹出菜单项后的效果:

PanelBar的Accordion效果

<UserControl x:Class="Telerik.Sample.Accordion"
    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" 
    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">

    <Grid>      
        
        <Grid.Resources>

            <telerik:ContainerBindingCollection x:Name="BindingsCollection">
                <!--用于将工作间组的展开状态,与数据项的IsSelected绑定-->
                <telerik:ContainerBinding PropertyName="IsExpanded" Binding="{Binding IsSelected, Mode=TwoWay}" />              
            </telerik:ContainerBindingCollection>
            
           <!--菜单项模板-->
            <telerik:HierarchicalDataTemplate x:Key="ChildTemplate">
                <StackPanel>
                    <Image Source="{Binding ImageUri}" Width="48" Height="48"></Image>
                    <TextBlock Text="{Binding Text}" Margin="0,5,0,0" TextAlignment="Center"></TextBlock>
                </StackPanel>
            </telerik:HierarchicalDataTemplate>
            
            <!--菜单组模板-->
            <telerik:HierarchicalDataTemplate x:Key="ParentTemplate" ItemTemplate="{StaticResource ChildTemplate}" ItemsSource="{Binding Children}" telerik:ContainerBinding.ContainerBindings="{StaticResource BindingsCollection}">
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding ImageUri}" Width="24" Height="24" Margin="5,0,5,0"></Image>
                    <TextBlock Text="{Binding Text}" Margin="0,2,0,0" FontSize="14" FontWeight="Bold"></TextBlock>
                </StackPanel>
            </telerik:HierarchicalDataTemplate>
        </Grid.Resources>
        
        <telerik:RadPanelBar Background="White" Orientation="Vertical"
                VerticalAlignment="Top" HorizontalAlignment="Left" ExpandMode="Single" Width="150" ItemTemplate="{StaticResource ParentTemplate}" ItemsSource="{Binding Source={StaticResource SampleDataSource}, Path=SampleMenuItemCollection}">
            <!--<telerik:RadPanelBarItem  IsExpanded="True" Header="基础数据" >            	        
                <StackPanel>
                   <telerik:RadButton Margin="0,3">
                        <StackPanel>
                            <Image Source="/Common.Silverlight.Resource;component/img/Book.png" Width="64" Height="64" ></Image>
                            <TextBlock TextAlignment="Center">部门管理</TextBlock>
                        </StackPanel>
                    </telerik:RadButton>
                      <telerik:RadButton Margin="0,3">
                        <StackPanel>
                            <Image Source="/Common.Silverlight.Resource;component/img/Book_Open.png" Width="64" Height="64" ></Image>
                            <TextBlock TextAlignment="Center" Text="adfasdfasdf"/>
                        </StackPanel>
                    </telerik:RadButton>
                </StackPanel>
            </telerik:RadPanelBarItem>
            <telerik:RadPanelBarItem Header="报文管理">
                <StackPanel>
                    <telerik:RadButton Content="FFM报文计划"  />
                    <telerik:RadButton Content="FSU报文计划" />
                </StackPanel>
            </telerik:RadPanelBarItem>-->
        </telerik:RadPanelBar>
    </Grid>


</UserControl>

运行时截图:

TabPanel+Frame

为了节省空间,将多个界面以Tab标签页方式整合在一起是常见的用法,每个标签页的内容通常是实例化一个单独的Xaml模块,可以考虑每个标签页的内容以Frame形式嵌入一个xaml

<UserControl 
    x:Class="Telerik.SampleIndex"
    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" 
     xmlns:local="clr-namespace:Telerik.Sample" 
    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">

    <Grid >       
        <telerik:RadTabControl 
				DisplayMemberPath="Content"  ScrollMode="Viewport"
				BorderThickness="0">
            <telerik:RadTabItem Header="测试Tab" IsSelected="True">
                <telerik:RadTabItem.Content>
                    <telerik:RadTreeView  IsLineEnabled="True" ItemsOptionListType="CheckList"  IsOptionElementsEnabled="True">
                        <telerik:RadTreeViewItem Header="中国航信" IsExpanded="True" DefaultImageSrc="/Common.Silverlight.Resource;component/img/Book_Open.png" >
                            <telerik:RadTreeViewItem Header="天信达"  DefaultImageSrc="/Common.Silverlight.Resource;component/img/Book.png">
                            </telerik:RadTreeViewItem>                            
                        </telerik:RadTreeViewItem>
                    </telerik:RadTreeView>
                </telerik:RadTabItem.Content>
            </telerik:RadTabItem>
            <telerik:RadTabItem Header="TreeView">               
                <telerik:RadTabItem.Content>
                    <telerik:RadFrame HorizontalAlignment="Left"  x:Name="radFrame1" VerticalAlignment="Top" >
                        <local:TreeView/>
                    </telerik:RadFrame>
                </telerik:RadTabItem.Content>
            </telerik:RadTabItem>
            <telerik:RadTabItem Header="Accordion">               
                <telerik:RadTabItem.Content>
                    <telerik:RadFrame HorizontalAlignment="Left"  x:Name="radFrame2" VerticalAlignment="Top" >
                        <local:Accordion/>
                    </telerik:RadFrame>
                </telerik:RadTabItem.Content>
            </telerik:RadTabItem>           
        </telerik:RadTabControl>
    </Grid>

</UserControl>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

扫码关注云+社区

领取腾讯云代金券