How to consume a TAB/Enter KeyPressed on the TextArea, and replace with focustraversal or enter key without using internal API? - textarea

I need to have a control which will wordwrap, add scrollbars, etc - but ignore the enter key and jump to the next control using tab/shift tab. I can't seem to get this right.
This is the control I have done, and it seems to just simply stay in the text area. (This was used from an old example online and it seems to work only if the textArea is in the same node as the rest).
public class TabAndEnterIgnoringTextArea extends TextArea {
final TextArea myTextArea = this;
public TabAndEnterIgnoringTextArea() {
this.setWrapText(true);
addEventFilter(KeyEvent.KEY_PRESSED, new TabAndEnterHandler());
}
private class TabAndEnterHandler implements EventHandler<KeyEvent> {
private KeyEvent recodedEvent;
#Override
public void handle(KeyEvent event) {
if (recodedEvent != null) {
recodedEvent = null;
return;
}
Parent parent = getParent();
if (parent != null) {
switch (event.getCode()) {
case ENTER:
if (event.isControlDown()) {
recodedEvent = recodeWithoutControlDown(event);
myTextArea.fireEvent(recodedEvent);
} else {
Event parentEvent = event.copyFor(parent, parent);
myTextArea.getParent().fireEvent(parentEvent);
}
event.consume();
break;
case TAB:
if (event.isControlDown()) {
recodedEvent = recodeWithoutControlDown(event);
myTextArea.fireEvent(recodedEvent);
} else if (event.isShiftDown()) {
ObservableList<Node> children = FXCollections.observableArrayList();
addAllDescendents(parent, children);
int idx = children.indexOf(myTextArea);
if (idx > 0) {
for (int i = idx - 1; i > 0; i--) {
if (children.get(i).isFocusTraversable()) {
children.get(i).requestFocus();
break;
}
}
}
} else {
ObservableList<Node> children = FXCollections.observableArrayList();
addAllDescendents(parent, children);
int idx = children.indexOf(myTextArea);
if (idx >= 0) {
for (int i = idx + 1; i < children.size(); i++) {
if (children.get(i).isFocusTraversable()) {
children.get(i).requestFocus();
break;
}
}
if (idx + 1 >= children.size()) {
for (int i = 0; i < idx; i++) {
if (children.get(i).isFocusTraversable()) {
children.get(i).requestFocus();
break;
}
}
}
}
}
event.consume();
break;
default:
break;
}
}
}
private void addAllDescendents(Parent parent, ObservableList<Node> nodes) {
for (Node node : parent.getChildrenUnmodifiable()) {
nodes.add(node);
if (node instanceof Parent)
addAllDescendents((Parent) node, nodes);
}
}
private KeyEvent recodeWithoutControlDown(KeyEvent event) {
return new KeyEvent(event.getEventType(), event.getCharacter(), event.getText(), event.getCode(),
event.isShiftDown(), false, event.isAltDown(), event.isMetaDown());
}
}
Once I land in my field, it won't leave with the keyboard. Any ideas? Also - I shouldn't assume that the next control is actually in the nodes within my parent, as the control may be part of another control where its the last control and the next one might be on the parent above.
Basically I want the next landable item in the scenegraph.
I am able to do it with internal API - but I know that is very discouraged.
public class TabAndEnterIgnoringTextArea extends TextArea {
final TextArea myTextArea = this;
public TabAndEnterIgnoringTextArea() {
addEventFilter(KeyEvent.KEY_PRESSED, new TabAndEnterHandler());
}
class TabAndEnterHandler implements EventHandler<KeyEvent> {
private KeyEvent recodedEvent;
#Override
public void handle(KeyEvent event) {
if (recodedEvent != null) {
recodedEvent = null;
return;
}
Parent parent = myTextArea.getParent();
Scene scene = parent.getScene();
while (scene == null){
parent = parent.getParent();
scene = parent.getScene();
}
SceneTraversalEngine engine = new SceneTraversalEngine(getScene());
if (parent != null) {
switch (event.getCode()) {
case ENTER:
if (event.isControlDown()) {
recodedEvent = recodeWithoutControlDown(event);
myTextArea.fireEvent(recodedEvent);
} else {
Event parentEvent = event.copyFor(parent, parent);
myTextArea.getParent().fireEvent(parentEvent);
}
event.consume();
break;
case TAB:
if(event.isShiftDown()){
engine.trav(myTextArea, Direction.PREVIOUS);
}else {
engine.trav(myTextArea, Direction.NEXT);
}
}
}
}
private KeyEvent recodeWithoutControlDown(KeyEvent event) {
return new KeyEvent(event.getEventType(), event.getCharacter(), event.getText(), event.getCode(),
event.isShiftDown(), false, event.isAltDown(), event.isMetaDown());
}
}
}
Thanks

I think I found a solution which will allow me to have this work as designed.
public class TabAndEnterIgnoringTextArea extends TextArea {
final TextArea myTextArea = this;
public TabAndEnterIgnoringTextArea() {
this.setWrapText(true);
addEventFilter(KeyEvent.KEY_PRESSED, new TabAndEnterHandler());
}
private class TabAndEnterHandler implements EventHandler<KeyEvent> {
#Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.TAB || event.getCode() == KeyCode.ENTER) {
event.consume();
if(event.getCode() == KeyCode.TAB){
selectNextNode(!event.isShiftDown());
}
}
}
private void selectNextNode(boolean forward){
List<Node> nodes = getAllNodes(myTextArea.getScene().getRoot());
int index = nodes.indexOf(myTextArea);
if(forward){
if(index < nodes.size() - 1) {
nodes.get(index + 1).requestFocus();
}else {
nodes.get(0).requestFocus();
}
}else {
if(index == 0) {
nodes.get(nodes.size() - 1).requestFocus();
}else {
nodes.get(index - 1).requestFocus();
}
}
}
private ArrayList<Node> getAllNodes(Parent root) {
ArrayList<Node> nodes = new ArrayList<Node>();
addAllDescendents(root, nodes);
return nodes;
}
private void addAllDescendents(Parent parent, ArrayList<Node> nodes) {
for (Node node : parent.getChildrenUnmodifiable()) {
if(node.isFocusTraversable()){
nodes.add(node);
}
if (node instanceof Parent)
addAllDescendents((Parent)node, nodes);
}
}
}
}
If you see anything wrong with this approach I would appreciate it, but it seems to work for my purposes.

Related

Why Vaadin TreeGrid loads the data two times after Scrolling?

I have the following issue: When my Treegrid gets loaded for the first time, all the root data where correct added. But when i scroll drown in the TreeGrid, the data are picked up again and added to the Treegrid.
Does anyone know how to deactivate lazy loading in a Treegrid when scrolling?
Here is my Method which created the Treegrid
private Component createCategoriesTree() {
treeGrid.setHeight("100%");
treeGrid.addComponentHierarchyColumn(productCategory -> getProductCategoryName(productCategory)).setHeader("Kategorie").setSortable(false);
ProductCategory root = productCategoriesService.getRootCategory();
HierarchicalDataProvider dataProvider = new AbstractBackEndHierarchicalDataProvider<ProductCategory, Void>() {
#Override
public int getChildCount(HierarchicalQuery<ProductCategory, Void> query) {
if (query.getParent() == null) {
List<ProductCategory> list = productCategoriesService.findByParentId(root.getId());
return (int) list.size();
} else {
List<ProductCategory> list = productCategoriesService.findByParentId(query.getParent().getId());
return (int) list.size();
}
}
#Override
public boolean hasChildren(ProductCategory item) {
List<ProductCategory> list = productCategoriesService.findByParentId(item.getId());
if (list != null && list.size() > 0) {
return true;
} else {
return false;
}
}
#Override
protected Stream<ProductCategory> fetchChildrenFromBackEnd(HierarchicalQuery<ProductCategory, Void> query) {
if (query.getParent() == null) {
return productCategoriesService.findByParentId(root.getId()).stream();
} else {
return productCategoriesService.findByParentId(query.getParent().getId()).stream();
}
}
};
treeGrid.setDataProvider(dataProvider);
return treeGrid;
}
The issue was:
missing skip method like following method body:
#Override
protected Stream<ProductCategory> fetchChildrenFromBackEnd(HierarchicalQuery<ProductCategory, Void> query) {
if (query.getParent() == null) {
return productCategoriesService.findByParentIdOrderByCategoryNameAsc(root.getId()).stream().skip(query.getOffset()).limit(query.getLimit()); //THIS
} else {
return productCategoriesService.findByParentIdOrderByCategoryNameAsc(query.getParent().getId()).stream(); //THIS
}
}

Simplify a switch statement

I would like to sum up the code below to make it less and more beautiful.
I have 5 models (User, Group, Event, Member, Appearance), three shown below.
I’d like to simplify the code.
String getId(uri) {
String pathSegment;
if (uri.pathSegments.length >= 2) {
pathSegment = uri.pathSegments[1];
} else {
return null;
}
switch (resource) {
case 'users':
for (User user in models[resource]) {
if (user.id == pathSegment) {
return pathSegment;
} else {
return null;
}
}
break;
case 'groups':
for (Group group in models[resource]) {
if (group.id == pathSegment) {
return pathSegment;
} else {
return null;
}
}
break;
case 'events':
for (Event event in models[resource]) {
if (event.id == pathSegment) {
return pathSegment;
} else {
return null;
}
}
break;
default:
break;
}
return null;
}
If your User, Group, and Event have a common id, then You can simplify your code by using dynamic type. See related documentation.
String getId(uri) {
String pathSegment;
if (uri.pathSegments.length >= 2) {
pathSegment = uri.pathSegments[1];
} else {
return null;
}
return _getIdFromItems(models[resource], pathSegment);
}
String _getIdFromItems(List<dynamic> items, String pathSegment) {
for (dynamic item in items) {
if (item.id == pathSegment) {
return pathSegment;
} else {
return null;
}
}
return null;
}

Listview Filter with SearchView Using Base Adapter in Xamarin android Error

I am try to filter listview with searchview using Base Adapter in in xamarin Android, My listView Bind in sql server using restfull web service i am stuck in PublishResults which is given an error
Here Is My Code:-
GetHospNames.cs
public class GetHospNames
{
public string HospID { get; set; }
public string HospName { get; set; }
public GetHospNames(string HospID, string HospName)
{
this.HospID = HospID;
this.HospName = HospName;
//this.HospLogo = HospLogo;
}
}
ContListViewHospNameClass.cs
using System.Collections.Generic;
using Android.App;
using Android.Views;
using Android.Widget;
using System;
using Android.Graphics;
using Android.Graphics.Drawables;
using System.IO;
using Android.Content;
using Java.Lang;
using Android.Text;
using Java.Util;
using Oject = Java.Lang.Object;
namespace HSAPP
{
public class ContListViewHospNameClass : BaseAdapter<GetHospNames>, IFilterable
{
public List<GetHospNames> objList;
Activity objActivity;
List<GetHospNames> filterList;
public ContListViewHospNameClass(Activity objMyAct, List<GetHospNames> objMyList) : base()
{
this.objActivity = objMyAct;
objList = objMyList;
this.filterList = objList;
Filter = new CustomFilter(this);
}
public override GetHospNames this[int position]
{
get
{
return objList[position];
}
}
public override int Count
{
get
{
return objList.Count;
}
}
public Filter Filter { get; set; }
public override void NotifyDataSetChanged()
{
base.NotifyDataSetChanged();
}
//This is Inner Class
public class CustomFilter : Filter
{
ContListViewHospNameClass CustomAdapter;
public CustomFilter(ContListViewHospNameClass adapter) : base()
{
this.CustomAdapter = adapter;
}
protected override FilterResults PerformFiltering(ICharSequence constraint)
{
FilterResults result = new FilterResults();
if (constraint != null && constraint.Length() > 0)
{
//Contraint To Upper
List<GetHospNames> filter = new List<GetHospNames>();
foreach (GetHospNames name in CustomAdapter.objList)
{
if (name.HospName.ToUpper().Contains(constraint.ToString().ToUpper()))
{
filter.Add(name);
}
}
Oject[] Name;
Name = new Oject[filter.Count];
for (int i = 0; i < filter.Count; i++)
{
Name[i] = filter[i].HospName.ToString();
}
result.Count = filter.Count;
result.Values = Name;
}
return result;
}
protected override void PublishResults(ICharSequence constraint, Filter.FilterResults result)
{
List<GetHospNames> filteredList = new List<GetHospNames>();
for (int i = 0; i < ((Oject[])result.Values).Length; i++)
{
filteredList.Add((Oject[])result.Values[i]);//Here Is An Error *****Cannot apply indexing with [] to an expression of type 'Object'****
}
CustomAdapter.objList = filteredList;
CustomAdapter.NotifyDataSetChanged();
}
}
public override long GetItemId(int position)
{
return position;
}
public Bitmap getBitmap(byte[] getByte)
{
if (getByte.Length != 0)
{
return BitmapFactory.DecodeByteArray(getByte, 0, getByte.Length);
}
else
{
return null;
}
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = objList[position];
if (convertView == null)
{
convertView = objActivity.LayoutInflater.Inflate(Resource.Layout.ContListViewHospName, null);
}
convertView.FindViewById<TextView>(Resource.Id.tvHospID).Text = item.HospID;
convertView.FindViewById<TextView>(Resource.Id.tvHospName).Text = item.HospName;
return convertView;
}
}
public static class ObjectTypeHelper
{
public static T Cast<T>(this Java.Lang.Object obj) where T : class
{
var propertyInfo = obj.GetType().GetProperty("Instance");
return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
}
}
}
This is my MainActivity Code
private void BindControl_BindHospCompleted(object sender, BindControl.BindHospCompletedEventArgs e)
{
jsonValue = e.Result.ToString();
try
{
if (jsonValue == null)
{
Toast.MakeText(this, "No Data For Bind", ToastLength.Long).Show();
return;
}
JArrayValue = JArray.Parse(jsonValue);
list = new List<GetHospNames>();
int count = 0;
while (count < JArrayValue.Count)
{
GetHospNames getHospName = new GetHospNames(JArrayValue[count]["HospID"].ToString(), JArrayValue[count]["HospName"].ToString());
list.Add(getHospName);
count++;
}
if (count == 0)
{
Toast.MakeText(this, "No List Of Hospitals", ToastLength.Long).Show();
}
adapter = new ContListViewHospNameClass(this, list);
listView.Adapter = adapter;
search.QueryTextChange += (s, e) =>
{
adapter.Filter.InvokeFilter(e.NewText);
};
listView.ItemClick += ListView_ItemClick;
pBar.Dismiss();
}
catch (Java.Lang.Exception ex)
{
pBar.Dismiss();
//Toast.MakeText(this, ex.ToString(), ToastLength.Long).Show();
Finish();
Intent intent = new Intent(this, typeof(ChkIntConnActivity));
StartActivity(intent);
}
}
Please Help...Thank You

how to use multi choice spinner in mono for android?

I want to use multi choice spinner in mono for android.
I want to bind the countries to the spinner
Now in the normal spinner there is label with radio button.
But I want the label with the Checkbox.
can any one please help me.
AlertDialog.Builder alt_bld = new AlertDialog.Builder(
CareCardActivity.this);
alt_bld.setTitle("Select Recepients");
alt_bld.setMultiChoiceItems(tempname, new boolean[tempname.length] , new DialogInterface.OnMultiChoiceClickListener() {
public void onClick(DialogInterface dialog, int which,
boolean isChecked) {
// TODO Auto-generated method stub
}
});
alt_bld.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
ListView list = ((AlertDialog) dialog).getListView();
Log.v("LIST COUNT:: ", ""+list.getCount());
for (int i = 0; i < list.getCount(); i++) {
boolean checked = list.isItemChecked(i);
if (checked) {
sb.append(contactNumber[i]).append(";");
}
}
sb = sb.replace(
sb.length() - 1,
sb.length(), "");
txtPhoneNo.setText(sb.toString());
}
});
alt_bld.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
AlertDialog alert = alt_bld.create();
alert.show();
I have tried this code in the eclipse it is working fine in it, but I want to do it for Mono develop in C#.
call this function on click of button
ShowDialog(DIALOG_MULTIPLE_CHOICE);
Add Following Code
protected override Dialog OnCreateDialog(int id)
{
switch (id) {
case DATE_DIALOG_ID:
return new DatePickerDialog(this, OnDateSet, date.Year, date.Month - 1, date.Day);
case DIALOG_MULTIPLE_CHOICE: {
var builder = new AlertDialog.Builder (this);
// builder.SetIcon (Resource.Drawable.ic_popup_reminder);
builder.SetTitle ("Select Country");
builder.SetMultiChoiceItems (countryName, new bool[countryName.Length], MultiListClicked);
builder.SetPositiveButton ("ok", OkClicked);
builder.SetNegativeButton ("Cancel", CancelClicked);
return builder.Create ();
}
}
return null;
}
private void MultiListClicked (object sender, DialogMultiChoiceClickEventArgs e)
{
Console.WriteLine ("countryMultiListClicked");
if (e.IsChecked) {
mSelectedItems.Add (countryName [(int)e.Which]);
mSelectedItemsID.Add (countryID [(int)e.Which]);
}
else if (mSelectedItems.Contains(countryName [(int)e.Which]))
{
mSelectedItems.Remove(countryName [(int)e.Which]);
mSelectedItemsID.Remove(countryID [(int)e.Which]);
}
}
private void OkClicked (object sender, DialogClickEventArgs e)
{
Console.WriteLine ("countryOkClicked");
String listString = "";
for (int i =0; i<mSelectedItems.Count; i++) {
listString += mSelectedItems [i] + ",";
}
if (listString.Length > 0) {
listString = listString.Remove (listString.Length - 1);
}
et_country.Text = listString;
listStringId = "";
for (int i =0; i<mSelectedItemsID.Count; i++) {
listStringId += mSelectedItemsID [i] + ",";
}
if (listStringId.Length > 0) {
listStringId = listStringId.Remove (listStringId.Length - 1);
}
Console.WriteLine (listStringId);
}
private void CancelClicked (object sender, DialogClickEventArgs e)
{
Console.WriteLine("countryCancelClicked");
}
This works fine ........!

asp.net mvc related, mainly a refactor question

can anyone think of a better way to do this?
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction()
{
NameValueDeserializer value = new NameValueDeserializer();
// selected messages
MemberMessageSaveAction[] messages = (MemberMessageSaveAction[])value.Deserialize(Request.Form, "value", typeof(MemberMessageSaveAction[]));
// selected action
MemberMessageAction action = (MemberMessageAction)Enum.Parse(typeof(MemberMessageAction), Request.Form["action"]);
// determine action
if (action != MemberMessageAction.MarkRead &&
action != MemberMessageAction.MarkUnRead &&
action != MemberMessageAction.Delete)
{
// selected action requires special processing
IList<MemberMessage> items = new List<MemberMessage>();
// add selected messages to list
for (int i = 0; i < messages.Length; i++)
{
foreach (int id in messages[i].Selected)
{
items.Add(MessageRepository.FetchByID(id));
}
}
// determine action further
if (action == MemberMessageAction.MoveToFolder)
{
// folders
IList<MemberMessageFolder> folders = FolderRepository.FetchAll(new MemberMessageFolderCriteria
{
MemberID = Identity.ID,
ExcludedFolder = Request.Form["folder"]
});
if (folders.Total > 0)
{
ViewData["messages"] = items;
ViewData["folders"] = folders;
return View("move");
}
return Url<MessageController>(c => c.Index("inbox", 1)).Redirect();
}
else if (action == MemberMessageAction.ExportXml)
{
return new MemberMessageDownload(Identity.ID, items, MemberMessageDownloadType.Xml);
}
else if (action == MemberMessageAction.ExportCsv)
{
return new MemberMessageDownload(Identity.ID, items, MemberMessageDownloadType.Csv);
}
else
{
return new MemberMessageDownload(Identity.ID, items, MemberMessageDownloadType.Text);
}
}
else if (action == MemberMessageAction.Delete)
{
for (int i = 0; i < messages.Length; i++)
{
foreach (int id in messages[i].Selected)
{
MemberMessage message = MessageRepository.FetchByID(id);
if (message.Sender.ID == Identity.ID || message.Receiver.ID == Identity.ID)
{
if (message.Sender.ID == Identity.ID)
{
message.SenderActive = false;
}
else
{
message.ReceiverActive = false;
}
message.Updated = DateTime.Now;
MessageRepository.Update(message);
if (message.SenderActive == false && message.ReceiverActive == false)
{
MessageRepository.Delete(message);
}
}
}
}
}
else
{
for (int i = 0; i < messages.Length; i++)
{
foreach (int id in messages[i].Selected)
{
MemberMessage message = MessageRepository.FetchByID(id);
if (message.Receiver.ID == Identity.ID)
{
if (action == MemberMessageAction.MarkRead)
{
message.ReceiverRead = true;
}
else
{
message.ReceiverRead = false;
}
message.Updated = DateTime.Now;
MessageRepository.Update(message);
}
}
}
}
return Url<MessageController>(c => c.Index("inbox", 1)).Redirect();
}
I think you can also leverage the mvc framework for most of your code. Correct me if I'm wrong because I'm gonna make a few assumptions about your classes because I can't deduct it from your post.
My assumptions:
Request.Form["action"] is a single value selectbox
Request.Form["value"] is a multy value selectbox
action is the kind of action you want to be taken on all the messages
message is the list of values that should go with the action
I would try to leverage the framework's functionality where possible
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveMemberAction(SelectList selectedMessages, MemberMessageAction actionType){
//Refactors mentioned by others
}
If you then give your inputs in your Html the correct name (in my example that would be selectedMessages and actionType) the first few rules become unnessecary.
If the default modelBinder cannot help you, you might want to consider putting the parsing logic in a custom modelbinder. You can search SO for posts about it.
As a side note: you might want to reconsider your variable namings. "action" might be confusing with MVC's action (like in ActionResult) and MemberMessageSaveAction might look like it's a value of MemberMessageAction enum. Just a thought.
The first step will be making different methods for each action.
Next is to remove the negative logic.
This results in something like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction() {
// SNIP
if (action == MemberMessageAction.Delete) {
return DoDeleteAction(...);
}
else if (action == MemberMessageAction.MoveToFolder) {
return DoMoveToFolderAction(...);
}
else if (action == MemberMessageAction.ExportXml) {
return DoExportXmlAction(...);
}
else if (action == MemberMessageAction.ExportCsv) {
return DoExportCsvAction(...);
}
else {
return HandleUnknownAction(...);
}
}
Turn MemberMessageAction into a class that has a Perform virtual function.
For your Special actions, group the common Perform code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveAction()
{
NameValueDeserializer value = new NameValueDeserializer();
MemberMessageSaveAction[] messages = (MemberMessageSaveAction[])value.Deserialize(Request.Form, "value", typeof(MemberMessageSaveAction[]));
MemberMessageAction action = MemberMessageAction.FromName(
messages,
Request.Form["action"]));
return action.Perform();
}
class MoveToFolder : SpecialAction { /*...*/ }
class ExportXml : SpecialAction { /*...*/ }
class ExportCsv : SpecialAction { /*...*/ }
class Delete : MemberMessageAction { /*...*/ }
class MarkRead : MemberMessageAction { /*...*/ }
class MarkUnRead : MemberMessageAction { /*...*/ }
abstract class MemberMessageAction {
protected MemberMessageSaveAction[] messages;
public MemberMessageAction(MemberMessageSaveAction[] ms) { messages = ms; }
public abstract ActionResult Perform();
public static MemberMessageAction FromName(MemberMessageSaveAction[] ms, string action) {
// stupid code
// return new Delete(ms);
}
}
abstract class SpecialAction : MemberMessageAction {
protected IList<MemberMessage> items;
public SpecialAction(MemberMessageSaveAction[] ms) : base(ms) {
// Build items
}
}
Now you can easily factor the code.
I don't like
MessageRepository.FetchByID(messages[i].ID)
this will make messages.Length (selected) queries to the database. I think you need to store your messages in ViewData, perform a filtering and pass them to Update() without the need to requery your database.
I came up with this.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update(MemberMessageUpdate[] messages, MemberMessage.Action action)
{
var actions = new List<MemberMessage.Action>
{
MemberMessage.Action.MoveToFolder,
MemberMessage.Action.ExportCsv,
MemberMessage.Action.ExportText,
MemberMessage.Action.ExportText
};
if (actions.Contains(action))
{
IList<MemberMessage> items = new List<MemberMessage>();
for (var i = 0; i < messages.Length; i++)
{
if (messages[i].Selected == false)
{
continue;
}
items.Add(MessageRepository.FetchByID(messages[i].ID));
}
if (action == MemberMessage.Action.MoveToFolder)
{
var data = new MessageMoveViewData
{
Messages = items
};
return View("move", data);
}
return new MessageDownloadResult(Identity.ID, items, action);
}
MessageRepository.Update(messages, action);
return Url<MessageController>(c => c.Index(null, null, null, null)).Redirect();
}

Resources