• Silverlight实现ComboGrid功能


        Silverlight带了Combox控件,但这个控件只能选择不能编辑,虽然它能定义Item外观,但如果下拉选择是一个DataGrid控件似乎就不好定义了.还好Silverlight提供了一个灵活的Popup控件,通过它能实现类似于ComboGrid的功能.

        先看一下需要的功能效果:

        我们需要在选择项后自动地把选择的数据填充到相关性的两个TextBox中.实现这个功能我们选择了TextBox,Button和一个自定义的Popup DataGrid用户控件.由于Popup只负责显示但我们需要解决一些总是,就是当Popup显示的时候点击自身或其他区域就自动关闭,所以需用要把Popup DataGrid封装一起方便处理.

        以下是这个Popup DataGrid的实现

    <UserControl x:Class="ComboGrid.ComboGrid"
        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:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" Loaded="UserControl_Loaded">
        
        <Grid x:Name="LayoutRoot" Background="#09FFFFFF" MouseRightButtonDown="LayoutRoot_MouseRightButtonDown" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown">
            <sdk:DataGrid AutoGenerateColumns="False"  HorizontalAlignment="Left" Name="dataGrid1" VerticalAlignment="Top" Width="253"  MouseLeftButtonDown="dataGrid1_MouseLeftButtonDown" SelectionChanged="dataGrid1_SelectionChanged">
                <sdk:DataGrid.Columns>
    
                    <sdk:DataGridTextColumn Binding="{Binding Name}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="120" Header="Name" />
                    <sdk:DataGridTextColumn Binding="{Binding Host}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="*" Header="Host" />
                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
        </Grid>
    </UserControl>

    LayoutRoot的背景设置非常重要,因为我们需要用它来做这遮罩,来捕获DataGrid周边的鼠标点击事件,为了不影响整个布局的外观好尽可能的设置接近秀明.给用户控件定义两个mouse down事件自动隐藏

    private void LayoutRoot_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
            {
                Hide();
            }
    
            private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                Hide();
            }

    为了让DataGrid排序等操作不触这两个事件,需要在DataGrid的LeftMouseDown设置一个属性值

    private void dataGrid1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                e.Handled = true;
            }

    这样DataGrid点击鼠标左键的时候就不会把Popup隐藏了.下面是给控件定义显示方法.

    public void Show(Control target,Point Offset)
            {
                mPopup = new Popup();
                this.Width = Application.Current.Host.Content.ActualWidth;
                this.Height = Application.Current.Host.Content.ActualHeight;
                GeneralTransform gt = target.TransformToVisual(Application.Current.RootVisual as UIElement);
                Point offset = gt.Transform(new Point(0, 0));
                double controlTop = offset.Y;
                double controlLeft = offset.X;
                Point postion= new Point(controlLeft + Offset.X, controlTop + Offset.Y);
                mPopup.Child = this;
                dataGrid1.Margin = new Thickness(postion.X, postion.Y, 0, 0);
                mPopup.IsOpen = true;
            }

    方法带两个参数,第一个是目标控件,是指Popup的位置就显示在这个控件之上,第二个方法就是偏移座标.最终通过修改DataGrid的Margin来达到所需位置的显示.控件隐藏方法代码相对也是非常简单

    public void Hide()
            {
                if (mPopup != null)
                {
                  
                    mPopup.IsOpen = false;
                    mPopup.Child = null;
                    mPopup = null;
                }
            }

     

     下面的工作就是处理DataGrid的SelectChanged需要做的事件,当我们改变选择项的同时触发一个事件告诉调用者和把当前Popup关闭即可.

    private void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (dataGrid1.SelectedItem != null )
                {
                    Hide();
                    if (Selected != null)
                        Selected((UserData)dataGrid1.SelectedItem);
                }
            }

    到这时Popup DataGrid的就已经封装完成,那实际调用代码如下:

    private ComboGrid mComboGrid = new ComboGrid();
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                mComboGrid.Show(textBox1, new Point(0, 26));
            }
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                mComboGrid.Selected += (s) => {
                    textBox1.Text = s.Name;
                    textBox2.Text = s.Host;
                };
            }

     

     Silverlight提供给我们的Popup可以实现的功能有很多,MessageBox,自定义Combox和右键菜单等等.迟下会讲解如何实现一个右键菜单.

    以下这个地址实现了这几种效果:sl.henryfan.net

           下载完整代码: ComboGrid.rar (1.88 mb) 

         

    访问Beetlex的Github
  • 相关阅读:
    python使用matplotlib的savefig保存时图片保存不清晰以及不完整的问题
    EventBus 讲解挺详细的例子
    webpack构建优化的一些点
    webpack tree-shaking 优化
    vue 自定义指令示例 v-prop
    webpack loader 开发实战 px-rpx-vw-loader
    Google商店
    前端 机器学习 pipcook
    object-fit 设置背景(内容)填充
    postMessage iframe 跨域通信
  • 原文地址:https://www.cnblogs.com/smark/p/2451392.html
Copyright © 2020-2023  润新知