【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)


相关推荐

发表回复

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

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