【WP7进阶】——分享一个可供切换状态的ListBox组件「建议收藏」

【WP7进阶】——分享一个可供切换状态的ListBox组件

大家好,又见面了,我是全栈君。

编写Asp.net的同学,经常会遇到一个Repeater 或者一个GridView ,当用户点击编辑状态时我们的列表组件会自动跳转到可选择(可供删除、编辑、选择等)状态。这时候一般的做法都会在组件的前方自动生成一系列复选框“CheckBox”,需要删除/选择哪行时只要在前方的复选框勾一下,便可以得到该行的数据或者行ID等。

  上面的做法是一个比较典型的Web做法,那么在WP7 里面要实现这样的效果如何实现呢?有些同学就会说了,那简单使用ListBox 在它的数据模板里面添加一个CheckBox不就完事了吗?是的,这样是一种做法,但带来的问题是你得去控制他选中哪行并且得到哪行的ID,并且在WP7 有限的屏幕中这种做法比较不妥,当用户想做选择时,我们才让对应的行有可供选择的状态才更佳。而这种做法在传统的WP7控件中,是没有的。因为我们必须时时去控制它的复选框显示或者隐藏,但在这里我推荐大家一个组件,自带CheckBOx并且默认有两种状态,一种为普通状态即呈现数据显示给用户,如下图:

【WP7进阶】——分享一个可供切换状态的ListBox组件「建议收藏」

另外一种状态为可选择状态,即用户可以对相应的行做删除等操作,如下图:

【WP7进阶】——分享一个可供切换状态的ListBox组件「建议收藏」

 

该组件的下载地址为:WindowsPhoneListBoxWithCheckBoxesControl

 

下面给出该组件的详细用法:

做过.Net 开发的对于如何使该组件的应该很清楚,这里将跳过此步骤。

  如上图,该组件编写的XAML代码为如下:

 

 
<
my:ListBoxWithCheckBoxes 
Name
=”listBoxWithBoxes”
 Margin
=”0,0,0,0″
 ItemsSource
=”
{Binding SimpleModels}

>

                

<
ListBox.ItemTemplate
>

                    

<
DataTemplate
>

                        

<
StackPanel 
Orientation
=”Horizontal”
 Margin
=”0,0,0,20″
>

                            

<
Rectangle 
Height
=”100″
 Width
=”100″
 Fill
=”#FFE5001b”
 Margin
=”12,0,9,0″
/>

                            

<
StackPanel
>

                                

<
TextBlock 
Text
=”
{Binding Name}

 TextWrapping
=”Wrap”
 Style
=”
{StaticResource PhoneTextLargeStyle}

/>

                                

<
TextBlock 
Text
=”
{Binding Description}

 TextWrapping
=”Wrap”
 Margin
=”12,-6,12,0″
 Style
=”
{StaticResource PhoneTextSubtleStyle}

/>

                            

</
StackPanel
>

                        

</
StackPanel
>

                    

</
DataTemplate
>

                

</
ListBox.ItemTemplate
>

  

</
my:ListBoxWithCheckBoxes
>

 

 

如上代码的数据模板,并未出现有CheckBox 控件,因为该组件己经将CheckBox控件整合在里面的选择状态中了。下面是具体如何为该组件添加数据。

首先该组件对应的行有标题和描述,这个在上面XAML代码中的数据模板可以看得出,查看该组件的ItemSource ,一起来看看它的代码是如何编写的:

 

public
 
class
 SimpleModel : INotifyPropertyChanged
    {

        

protected
 
string
 itsName;
        

protected
 
string
 itsDescription;

        
public
 
event
 PropertyChangedEventHandler PropertyChanged;

        
public
 
string
 Name 
        {

            

get
 { 
return
 
this
.itsName; }
            

set
 { 
this
.itsName 
=
 value; NotifyPropertyChanged(

Name

); }
        }

        
public
 
string
 Description
        {

            

get
 { 
return
 
this
.itsDescription; }
            

set
 { 
this
.itsDescription 
=
 value; NotifyPropertyChanged(

Description

); }
        }

        
protected
 
void
 NotifyPropertyChanged(
string
 thePropertyName) 
        {

            

if
 (
this
.PropertyChanged
!=
null
)
            {

                

this
.PropertyChanged(
this

new
 PropertyChangedEventArgs(thePropertyName));
            }
        }

    }

 

 

代码比较简单,封装了两个属性分别为他们注册PropertyChanged 事件响应数据变化。

 

而这个MODEL的数据来源于如下代码:

 

 
public
 
class
 ListModel : INotifyPropertyChanged
    {

        

public
 
event
 PropertyChangedEventHandler PropertyChanged;

        
public
 ObservableCollection
<
SimpleModel
>
 SimpleModels { 
get

private
 
set
; }

        
public
 
bool
 IsDataLoaded { 
get

private
 
set
; }

        
public
 ListModel() 
        {

            

this
.SimpleModels 
=
 
new
 ObservableCollection
<
SimpleModel
>
();
        }

        
///
 
<summary>

        

///
 加载数据
        

///
 
</summary>


        
public
 
void
 LoadData() 
        {

            

for
 (
int
 i 
=
 
1
; i 
<
 
1000
; i
++
)
            {

                

this
.SimpleModels.Add(
new
 SimpleModel() { Name 
=
 



 
+
 i 
+
 



, Description 
=
 

这是第

 
+
 i 
+
 

项数据

 });
            }
            

this
.IsDataLoaded 
=
 
true
;
        }

        
protected
 
void
 NotifyPropertyChanged(
string
 thePropertyName)
        {

            

if
 (
this
.PropertyChanged
!=
null
)
            {

                

this
.PropertyChanged(
this

new
 PropertyChangedEventArgs(thePropertyName));
            }
        }

    }

 

 

代码跟上边的代码差不多,这里多了调用加载数据的方法LoadData()为上面的每个Model赋值。而加载代码首先为其添加一个全局属性:

 

 
public
 
static
 ListBoxWithCheckBox.ViewModel.ListModel viewModel 
=
 
null
;

        
//
获取数据


        
public
 
static
 ViewModel.ListModel ViewModel 
        {

            

get
 {

                

if
 (viewModel
==
null
)
                {

                    viewModel 

=
 
new
 ViewModel.ListModel();
                }
                

return
 viewModel;
            }
        }

 

 

转到MainPage的code behind 代码里面,在构造函数里面为DataContext 赋值,这里赋值的话上下文即可得到数据源,代码如下:

  DataContext = App.ViewModel;

 

当应用程序导航进来时,调用加载全局属性去执行抓取数据的方法,代码如下:

 

  
protected
 
override
 
void
 OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {

            

if
 (
!
App.ViewModel.IsDataLoaded)
            {

                App.ViewModel.LoadData();
            }
            

base
.OnNavigatedTo(e);
        }

 

 

 

最后的运行效果,我们选择第1 、2条数据做为欲删除的对象,然后删除看有啥变化?

【WP7进阶】——分享一个可供切换状态的ListBox组件「建议收藏」

 

点击删除后的效果:

【WP7进阶】——分享一个可供切换状态的ListBox组件「建议收藏」

 

mainPage 的code behind 完整代码如下:

【WP7进阶】——分享一个可供切换状态的ListBox组件「建议收藏」
完整代码

using
 System;

using
 System.Collections.Generic;

using
 System.Linq;

using
 System.Net;

using
 System.Windows;

using
 System.Windows.Controls;

using
 System.Windows.Documents;

using
 System.Windows.Input;

using
 System.Windows.Media;

using
 System.Windows.Media.Animation;

using
 System.Windows.Shapes;

using
 Microsoft.Phone.Controls;

using
 Microsoft.Phone.Shell;

using
 ListBoxWithCheckBox.ViewModel;


namespace
 ListBoxWithCheckBox
{

    

public
 
partial
 
class
 MainPage : PhoneApplicationPage
    {

        
private
 ApplicationBar applicationBarChoose;
        

private
 ApplicationBarIconButton applicationBarIconButtonChoose;

        
private
 ApplicationBar applicationBarDeleteOrCancel;
        

private
 ApplicationBarIconButton applicationBarIconButtonDelete;
        

private
 ApplicationBarIconButton applicationBarIconButtonCancel;

        
//
 Constructor


        
public
 MainPage()
        {

            InitializeComponent();
            ConstructApplicationBar();
            DataContext 

=
 App.ViewModel;
            

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

        
void
 MainPage_Loaded(
object
 sender, RoutedEventArgs e)
        {

           
        }

        
protected
 
override
 
void
 OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {

            

if
 (
!
App.ViewModel.IsDataLoaded)
            {

                App.ViewModel.LoadData();
            }
            

base
.OnNavigatedTo(e);
        }

        
///
 
<summary>

        

///
 构建应用程序条
        

///
 
</summary>


        
private
 
void
 ConstructApplicationBar()
        {

            

#region
–应用程序条“选择”菜单–

            

this
.applicationBarChoose 
=
 
new
 ApplicationBar();
            

this
.applicationBarIconButtonChoose 
=
 
new
 ApplicationBarIconButton(
new
 Uri(

/content/ApplicationBar.Choose.png

,UriKind.Relative));
            

this
.applicationBarIconButtonChoose.Text 
=
 

选择

;
            

this
.applicationBarIconButtonChoose.Click 
+=
 
new
 EventHandler(applicationBarIconButtonChoose_Click);
            

this
.applicationBarChoose.Buttons.Add(
this
.applicationBarIconButtonChoose);
            

this
.applicationBarChoose.IsMenuEnabled 
=
 
true
;
            

this
.applicationBarChoose.IsVisible 
=
 
true
;
            

this
.ApplicationBar 
=
 
this
.applicationBarChoose;
            

#endregion

            
this
.applicationBarDeleteOrCancel 
=
 
new
 ApplicationBar();
            

#region
 –删除–

            

this
.applicationBarIconButtonDelete 
=
 
new
 ApplicationBarIconButton(
new
 Uri(

/content/ApplicationBar.Delete.png

,UriKind.Relative));
            

this
.applicationBarIconButtonDelete.Text 
=
 

删除

;
            

this
.applicationBarIconButtonDelete.Click 
+=
 
new
 EventHandler(applicationBarIconButtonDelete_Click);
            

#endregion

            
#region
 –取消–

            

this
.applicationBarIconButtonCancel 
=
 
new
 ApplicationBarIconButton(
new
 Uri(

/content/ApplicationBar.Cancel.png

,UriKind.Relative));
            

this
.applicationBarIconButtonCancel.Text 
=
 

取消

;
            

this
.applicationBarIconButtonCancel.Click 
+=
 
new
 EventHandler(applicationBarIconButtonCancel_Click);
            

#endregion

            
this
.applicationBarDeleteOrCancel.Buttons.Add(
this
.applicationBarIconButtonDelete);
            

this
.applicationBarDeleteOrCancel.Buttons.Add(
this
.applicationBarIconButtonCancel);
            

this
.applicationBarDeleteOrCancel.IsMenuEnabled 
=
 
true
;
            

this
.applicationBarDeleteOrCancel.IsVisible 
=
 
true
;

        }

        
///
 
<summary>

        

///
 listBox 为可选择状态
        

///
 
</summary>


        
private
 
void
 SwitchToChooseState()
        {

            

this
.listBoxWithBoxes.IsInChooseState 
=
 
true
;
            

this
.ApplicationBar 
=
 
this
.applicationBarDeleteOrCancel;
        }

        
///
 
<summary>

        

///
 listBox 为普通状态
        

///
 
</summary>


        
private
 
void
 SwitchToNormalState()
        {

            

this
.listBoxWithBoxes.IsInChooseState 
=
 
false
;
            

this
.ApplicationBar 
=
 
this
.applicationBarChoose;
        }

        
///
 
<summary>

        

///
 取消操作
        

///
 
</summary>

        

///
 
<param name=”sender”></param>

        

///
 
<param name=”e”></param>


        
void
 applicationBarIconButtonCancel_Click(
object
 sender, EventArgs e)
        {

            SwitchToNormalState();
        }

        
///
 
<summary>

        

///
 删除操作
        

///
 
</summary>

        

///
 
<param name=”sender”></param>

        

///
 
<param name=”e”></param>


        
void
 applicationBarIconButtonDelete_Click(
object
 sender, EventArgs e)
        {

            

if
 (MessageBox.Show(

你确定要删除选中项吗?

,

提示

,MessageBoxButton.OKCancel)
==
MessageBoxResult.OK)
            {

                

foreach
 (SimpleModel item 
in
 
this
.listBoxWithBoxes.SelectedItems)
                {

                    App.ViewModel.SimpleModels.Remove(item);
                }
                SwitchToNormalState();
            }
        }

        
///
 
<summary>

        

///
 选择操作
        

///
 
</summary>

        

///
 
<param name=”sender”></param>

        

///
 
<param name=”e”></param>


        
void
 applicationBarIconButtonChoose_Click(
object
 sender, EventArgs e)
        {

            SwitchToChooseState();
        }
    }
}

 

 

这里推荐一个小技巧,当我们编写动态数据时,又不想运行即想从代码IDE看到运行效果,类似于这样:

【WP7进阶】——分享一个可供切换状态的ListBox组件「建议收藏」

 

这个效果还是要借用PhoneApplicationPage 的DataContext属性,具体如下编写代码:

  • 编写一个数据xaml命名为:ViewModelSampleData.xaml 文件,该文件负责为SimpleModels 做数据,代码如下:
    <
    viewModels:ListModel 
        

    xmlns
    =”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
           
        xmlns:x

    =”http://schemas.microsoft.com/winfx/2006/xaml”

        xmlns:viewModels

    =”clr-namespace:ListBoxWithCheckBox.ViewModel”
    >

        
    <
    viewModels:ListModel.SimpleModels
    >

            

    <
    viewModels:SimpleModel 
    Name
    =”测试第一项”
     Description
    =”这是测试的第一个节点”
     
    />

            

    <
    viewModels:SimpleModel 
    Name
    =”测试第二项”
     Description
    =”这是测试的第二个节点”
     
    />

        

    </
    viewModels:ListModel.SimpleModels
    >

        

    </
    viewModels:ListModel
    >

     

  • 在MainPage文件的XAML界面为DataContext赋值,代码如下:
        d:DataContext=”{d:DesignData ViewModelSampleData.xaml}”

     

Tip:该效果只运用于没有运行即可查看效果,运行后将会忽略。

 

怎么样,该组件不错吧,大家下载后试试吧。

源码下载:

ListBoxWithCheckBox Demo

 本文转自 terry_龙 51CTO博客,原文链接:http://blog.51cto.com/terryblog/497004,如需转载请自行联系原作者

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/108046.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Java核心技术(基础知识一)

    Java核心技术(基础知识一)Java程序设计概述1.1Java“白皮书”的关键术语简单性我们希望构建一个无须深奥的专业训练就可以进行编程的系统,并且要符合当今的标准惯例。因此,尽管我们发现C++不太适用,但在设计Java的时候韩式尽可能地接近C++,以便系统更易于理解。Java剔除了C++中许多很少使用、难以理解、容易混淆地特性。在我们看来,这些特性带来地麻烦远远多于它们地好处。的确,Java地语法是C++的一个“纯净”版本。这里没有头文件、指针运算(甚至指针语法)、结构、联合、操作符重载、虚基类等。然而,设计者并

  • asp.net 跳转页面[通俗易懂]

    asp.net 跳转页面[通俗易懂]①response.redirect这个跳转页面的方法跳转的速度不快,因为它要走2个来回(2次postback),但他可以跳转到任何页面,没有站点页面限制(即可以由雅虎跳到新浪),同时不能跳过登录保护。但速度慢是其最大缺陷!redirect跳转机制:首先是发送一个http请求到客户端,通知需要跳转到新页面,然后客户端在发送跳转请求到服务器端。需要注意的是跳转后内部空间保存的所有数据信息将会

  • x390拆机图解_Thinkpadx390详细拆机图解

    x390拆机图解_Thinkpadx390详细拆机图解技术文档主体内容:可以认为是页面最想表达的内容总和。对于内容详情页来说,主体内容指从标题开始至正文内容结束,翻页区域也被视为主体内容,文章后的评论、分享、推荐等不视为主体内容。首屏:用户点击搜索结果后进入移动页面,不滑动屏幕即看到的所有内容,称为首屏。一屏:用户滑动屏幕至主体内容展现结束之前,在页面任意位置停留时看到的所有内容,称为一屏。移动端适配:为了使PC页面能够在移动端正常展现的手段,保证用…

  • emule最新服务器地址,emule更新服务器列表

    emule最新服务器地址,emule更新服务器列表《emule更新服务器列表》由会员分享,可在线阅读,更多相关《emule更新服务器列表(15页珍藏版)》请在人人文库网上搜索。1、emule是通过ED2K网络和KAD网络寻找、连接其他emule客户端的,所以服务器列表和KAD节点文件是emule的必需文件。有些新手由于下载官方原版emule压缩包或其他未集成这些必需文件的emule压缩包,从而出现“连接不上ED2K与KAD”问题。所以学会下载更新…

  • 电脑开机读不到固态硬盘怎么办_电脑读不到固态硬盘怎么办

    电脑开机读不到固态硬盘怎么办_电脑读不到固态硬盘怎么办电脑重启后发现电脑检测不出固态硬盘,这种情况大家不要慌张,下面就由学习啦小编跟大家分享电脑重启后读不到固态硬盘该怎么办,欢迎大家来阅读学习。电脑重启后读不到固态硬盘怎么办方法一1、首先进入BIOS后,选择“IDEHDDAutoDetection”项目,看是否可以检测到硬盘的存在,并核对型号是否一致,如果正常排除硬件问题,如果还不能找到硬盘,那么就是您的硬盘损坏或连接不正确。2、如果在bios…

  • virsh查看虚拟网络信息_kvm创建虚拟机

    virsh查看虚拟网络信息_kvm创建虚拟机1.virsh查看/管理虚拟机问题本案例要求熟悉KVM虚拟化的virsh管理工具的的基本使用,从命令行来操作虚拟机,完成以下基本任务:1)查看KVM服务器信息2)列出有哪些虚拟机、指定虚拟机的状态3)基本的开关机操作4)将虚拟机设置为自动运行方案virsh命令行管理的常见用法:1)virsh:直接进交互模式2)virshnodeinfo:查看KVM节点(服务器)信息3…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号