`
ijavagos
  • 浏览: 1191394 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

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

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

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

该组件的下载地址为:WindowsPhoneListBoxWithCheckBoxesControl

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

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

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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><my:ListBoxWithCheckBoxesName="listBoxWithBoxes"Margin="0,0,0,0"ItemsSource="{BindingSimpleModels}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanelOrientation="Horizontal"Margin="0,0,0,20">
<RectangleHeight="100"Width="100"Fill="#FFE5001b"Margin="12,0,9,0"/>
<StackPanel>
<TextBlockText="{BindingName}"TextWrapping="Wrap"Style="{StaticResourcePhoneTextLargeStyle}"/>
<TextBlockText="{BindingDescription}"TextWrapping="Wrap"Margin="12,-6,12,0"Style="{StaticResourcePhoneTextSubtleStyle}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</my:ListBoxWithCheckBoxes>

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

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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassSimpleModel:INotifyPropertyChanged
{
protectedstringitsName;
protectedstringitsDescription;

publiceventPropertyChangedEventHandlerPropertyChanged;

publicstringName
{
get{returnthis.itsName;}
set{this.itsName=value;NotifyPropertyChanged("Name");}
}


publicstringDescription
{
get{returnthis.itsDescription;}
set{this.itsDescription=value;NotifyPropertyChanged("Description");}
}



protectedvoidNotifyPropertyChanged(stringthePropertyName)
{
if(this.PropertyChanged!=null)
{
this.PropertyChanged(this,newPropertyChangedEventArgs(thePropertyName));
}
}

}

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

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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassListModel:INotifyPropertyChanged
{
publiceventPropertyChangedEventHandlerPropertyChanged;

publicObservableCollection<SimpleModel>SimpleModels{get;privateset;}



publicboolIsDataLoaded{get;privateset;}

publicListModel()
{
this.SimpleModels=newObservableCollection<SimpleModel>();
}


///<summary>
///加载数据
///</summary>
publicvoidLoadData()
{
for(inti=1;i<1000;i++)
{
this.SimpleModels.Add(newSimpleModel(){Name=""+i+"",Description="这是第"+i+"项数据"});
}
this.IsDataLoaded=true;
}


protectedvoidNotifyPropertyChanged(stringthePropertyName)
{
if(this.PropertyChanged!=null)
{
this.PropertyChanged(this,newPropertyChangedEventArgs(thePropertyName));
}
}

}

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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicstaticListBoxWithCheckBox.ViewModel.ListModelviewModel=null;

//获取数据
publicstaticViewModel.ListModelViewModel
{
get{
if(viewModel==null)
{
viewModel
=newViewModel.ListModel();
}
returnviewModel;
}
}

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

DataContext = App.ViewModel;

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

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->protectedoverridevoidOnNavigatedTo(System.Windows.Navigation.NavigationEventArgse)
{
if(!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
base.OnNavigatedTo(e);
}

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

点击删除后的效果:

mainPage 的code behind 完整代码如下:

完整代码
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Net;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Animation;
usingSystem.Windows.Shapes;
usingMicrosoft.Phone.Controls;
usingMicrosoft.Phone.Shell;
usingListBoxWithCheckBox.ViewModel;

namespaceListBoxWithCheckBox
{
publicpartialclassMainPage:PhoneApplicationPage
{

privateApplicationBarapplicationBarChoose;
privateApplicationBarIconButtonapplicationBarIconButtonChoose;

privateApplicationBarapplicationBarDeleteOrCancel;
privateApplicationBarIconButtonapplicationBarIconButtonDelete;
privateApplicationBarIconButtonapplicationBarIconButtonCancel;

//Constructor
publicMainPage()
{
InitializeComponent();
ConstructApplicationBar();
DataContext
=App.ViewModel;
this.Loaded+=newRoutedEventHandler(MainPage_Loaded);
}

voidMainPage_Loaded(objectsender,RoutedEventArgse)
{

}

protectedoverridevoidOnNavigatedTo(System.Windows.Navigation.NavigationEventArgse)
{
if(!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
base.OnNavigatedTo(e);
}


///<summary>
///构建应用程序条
///</summary>
privatevoidConstructApplicationBar()
{
#region--应用程序条“选择”菜单--
this.applicationBarChoose=newApplicationBar();
this.applicationBarIconButtonChoose=newApplicationBarIconButton(newUri("/content/ApplicationBar.Choose.png",UriKind.Relative));
this.applicationBarIconButtonChoose.Text="选择";
this.applicationBarIconButtonChoose.Click+=newEventHandler(applicationBarIconButtonChoose_Click);
this.applicationBarChoose.Buttons.Add(this.applicationBarIconButtonChoose);
this.applicationBarChoose.IsMenuEnabled=true;
this.applicationBarChoose.IsVisible=true;
this.ApplicationBar=this.applicationBarChoose;
#endregion


this.applicationBarDeleteOrCancel=newApplicationBar();
#region--删除--
this.applicationBarIconButtonDelete=newApplicationBarIconButton(newUri("/content/ApplicationBar.Delete.png",UriKind.Relative));
this.applicationBarIconButtonDelete.Text="删除";
this.applicationBarIconButtonDelete.Click+=newEventHandler(applicationBarIconButtonDelete_Click);
#endregion


#region--取消--
this.applicationBarIconButtonCancel=newApplicationBarIconButton(newUri("/content/ApplicationBar.Cancel.png",UriKind.Relative));
this.applicationBarIconButtonCancel.Text="取消";
this.applicationBarIconButtonCancel.Click+=newEventHandler(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>
privatevoidSwitchToChooseState()
{
this.listBoxWithBoxes.IsInChooseState=true;
this.ApplicationBar=this.applicationBarDeleteOrCancel;
}

///<summary>
///listBox为普通状态
///</summary>
privatevoidSwitchToNormalState()
{
this.listBoxWithBoxes.IsInChooseState=false;
this.ApplicationBar=this.applicationBarChoose;
}


///<summary>
///取消操作
///</summary>
///<paramname="sender"></param>
///<paramname="e"></param>
voidapplicationBarIconButtonCancel_Click(objectsender,EventArgse)
{
SwitchToNormalState();
}

///<summary>
///删除操作
///</summary>
///<paramname="sender"></param>
///<paramname="e"></param>
voidapplicationBarIconButtonDelete_Click(objectsender,EventArgse)
{
if(MessageBox.Show("你确定要删除选中项吗?","提示",MessageBoxButton.OKCancel)==MessageBoxResult.OK)
{
foreach(SimpleModeliteminthis.listBoxWithBoxes.SelectedItems)
{
App.ViewModel.SimpleModels.Remove(item);
}
SwitchToNormalState();
}
}

///<summary>
///选择操作
///</summary>
///<paramname="sender"></param>
///<paramname="e"></param>
voidapplicationBarIconButtonChoose_Click(objectsender,EventArgse)
{
SwitchToChooseState();
}
}
}

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

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

  • 编写一个数据xaml命名为:ViewModelSampleData.xaml 文件,该文件负责为SimpleModels 做数据,代码如下:
    <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><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:SimpleModelName="测试第一项"Description="这是测试的第一个节点"/>
    <viewModels:SimpleModelName="测试第二项"Description="这是测试的第二个节点"/>
    </viewModels:ListModel.SimpleModels>

    </viewModels:ListModel>

  • 在MainPage文件的XAML界面为DataContext赋值,代码如下:
    <!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->d:DataContext="{d:DesignDataViewModelSampleData.xaml}"

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

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

源码下载:

ListBoxWithCheckBox Demo


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics