Is there a way to conditionally load different user control as edit form based on some user action (Edit vs. Create)?
This is how I ended up doing it
protected void Page_Init(object sender, EventArgs e)
{
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.EditFormType = GridEditFormType.WebUserControl;
ctlBenefitLimitsGrid.ItemDataBound += BenefitLimitsGrid_ItemDataBound;
ctlBenefitLimitsGrid.ItemCommand += BenefitLimitsGrid_ItemCommand;
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.EditFormType = GridEditFormType.WebUserControl;
}
void BenefitLimitsGrid_ItemCommand(object source, GridCommandEventArgs e)
{
switch (e.CommandName)
{
case "Edit":
e.Item.OwnerTableView.IsItemInserted = false;
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.UserControlName =
#"UserControls/BenefitLimitEdit.ascx";
break;
case "Add":
{
InsertAddControl(e);
break;
}
case "Delete":
var benefitLimitId = Convert.ToInt32(e.CommandArgument);
Presenter.Delete(benefitLimitId);
Presenter.LoadView();
break;
case "Save":
IEditView item;
if (e.Item.GetType() == typeof(GridEditFormInsertItem))
{
item =
(IEditView)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
}
else
{
item = ((GridDataItem)e.Item).EditFormItem.FindControl(GridEditFormItem.EditFormUserControlID) as IEditView;
}
if (item != null && item.HasErrors)
{
e.Canceled = true;
return;
}
e.Item.Edit = false;
ctlBenefitLimitsGrid.MasterTableView.ClearEditItems();
Presenter.LoadView();
break;
case "SaveAndNew":
{
var benefitLimitCreate = (IBenefitLimitCreate)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
if (benefitLimitCreate.HasErrors)
{
e.Canceled = true;
return;
}
Presenter.LoadView();
InsertAddControl(e);
break;
}
}
}
private void InsertAddControl(GridCommandEventArgs e)
{
ctlBenefitLimitsGrid.MasterTableView.ClearEditItems();
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.UserControlName = #"UserControls/BenefitLimitCreate.ascx";
e.Item.OwnerTableView.InsertItem();
var insertedItem = e.Item.OwnerTableView.GetInsertItem();
var ctlBenefitLimitCreate = (BenefitLimitCreate)insertedItem.FindControl(GridEditFormItem.EditFormUserControlID);
ctlBenefitLimitCreate.Presenter.LoadView();
}
I think that there was an article in the Telerik online documentation (under Insert/Update/Delete -> HowTo chapter) which does exactly what you are after.
Dick
Related
When i click on the tab page () a new settings page comes on but it's not populated with the info i already entered but it i click on a button (Navigation.PushModalAsync(new SettingsPage());) the page comes on and its populated with info I entered. is there a difference between the two?
//for tab page
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Bldg"
x:Class="Bldg.HomePage" >
<local:HistoryLogPage Title="Log"/>
<local:AddDrainsPage Title="Add"/>
<local:SettingsPage Title="Edit Settings"/>
<Label x:Name="drain1Label" />
</TabbedPage>
//for click button
void NextpageButton_Clicked(object sender, System.EventArgs e)
{
Navigation.PushModalAsync(new SettingsPage());
}
//SettingsPage
namespace Bldg
{
public partial class SettingsPage : ContentPage
{
public static string item, username;
public static string location1, location2;
bool is1Empty = string.IsNullOrEmpty(Settings.n1LocationSettings);
bool is2Empty = string.IsNullOrEmpty(Settings.n2LocationSettings);
List<string> list;
public SettingsPage()
{
InitializeComponent();
drainquantity();
list = new List<string>();
list.Add("1");
list.Add("2");
locationPicker1.SelectedIndexChanged += drain1Handle_SelectedIndexChanged;
locationPicker2.SelectedIndexChanged += drain2Handle_SelectedIndexChanged;
//nameofpickerinxamlfile.On<iOS().SetUpdateMode(UpdateMode.WhenFinished);
locationPicker1.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
locationPicker2.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
drainxPicker.SelectedItem = Settings.DrainquantitySettings;
locationPicker1.SelectedItem = Settings.n1LocationSettings;
locationPicker2.SelectedItem = Settings.n2LocationSettings;
nameEntry.Text = Settings.NameSettings;
clearButton.IsVisible = false;
drainlocationPicker2.IsEnabled = false;
drainxPicker.SelectedItem = Settings.DrainquantitySettings;
}
//this is fired when user changes or selects new selection
void drainxHandle_SelectedIndexChanged(object sender, System.EventArgs e)
{
//to get the value of user selected going to be use in switch; then save in a
variable
var drainx = drainxPicker.Items[drainxPicker.SelectedIndex];
item = (string)drainxPicker.SelectedItem;
bool isdrainxEmpty = string.IsNullOrEmpty(Settings.DrainquantitySettings);
if (isdrainxEmpty == true)
{
//switch for user selected in drainpicker
switch (drainx)
{
case "1":
n1Gridrow.IsVisible = true;
locationPicker1.IsVisible = true;
n2Gridrow.IsVisible = false;
if (is1Empty == true)
{
drainxPicker.IsEnabled = true;
}
else
drainxPicker.IsEnabled = false;
break;
case "2":
n1Gridrow.IsVisible = true;
n2Gridrow.IsVisible = true;
locationPicker2.IsEnabled = false;
break;
} //switch end
}
else
{
drainxPicker.IsEnabled = false;
nameEntry.IsEnabled = false;
n1Gridrow.IsVisible = true;
n2Gridrow.IsVisible = true;
locationPicker1.IsEnabled = false;
locationPicker2.IsEnabled = false;
settingsaveButton.IsVisible = false;
}
}
void n1Handle_SelectedIndexChanged(object sender, System.EventArgs e)
{
location1 = (string)locationPicker1.SelectedItem;
if (is1Empty == true)
{
locationPicker2.IsEnabled = true;
n2Label.IsVisible = true;
locationPicker2.Items.Remove((string)locationPicker1.SelectedItem);
}
drainxPicker.IsEnabled = false;
locationPicker1.IsEnabled = false;
}
void n2Handle_SelectedIndexChanged(object sender, System.EventArgs e)
{
location2 = (string)locationPicker2.SelectedItem;
if (is2Empty == true)
{
locationPicker2.IsEnabled = true;
}
drainxPicker.IsEnabled = false;
locationPicker2.IsEnabled = false;
}
void nxy1()
{
foreach (var location in list)
{
locationPicker1.Items.Add(location);
}
}
void nxy2()
{
foreach (var location in list)
{
locationPicker2.Items.Add(location);
}
}
void settingsaveButton_Clicked(object sender, System.EventArgs e)
{
bool isNameEmpty = string.IsNullOrEmpty(nameEntry.Text);
if (isNameEmpty == true)
{
DisplayAlert("Enter Name", "PLEASE", "OK");
}
else
{
Navigation.PushModalAsync(new HomePage());
//saving to Settings
Settings.n1LocationSettings = location1;
Settings.n2LocationSettings = location2;
Settings.NameSettings = username;
Settings.DrainquantitySettings = item;
drainxPicker.IsEnabled = false;
}
}
void entryNameHandle_Unfocused(object sender, Xamarin.Forms.FocusEventArgs e)
{
username = nameEntry.Text;
}
void clearHandle_Clicked(object sender, System.EventArgs e)
{
Settings.ClearAllData();
}
}
}
I expect that when i click on tabbed settings page, i go to the settings page with info entered populated. just like the button click it goes to settings page already populated with user entered.
Generally, tabbed settings page and pushed settings page is the same. They are all new fresh settings page.
From your code, we can see that you are setting the value of Picker by Settings plugin:
drainxPicker.SelectedItem = Settings.DrainquantitySettings;
locationPicker1.SelectedItem = Settings.n1LocationSettings;
locationPicker2.SelectedItem = Settings.n2LocationSettings;
So, whether the info entered will be populated or not when you go to the setting page is depending on the values in Settings.
For example:
If Settings.DrainquantitySettings; has value, then drainxPicker's info will be populated.
Check the Values in your Setting when you go to tabbed settings page and pushed settings page to find any difference.
Is there a way to multi-select in a Windows Tree View? Similar to the image below
I know that .NET currently doesn't have a multiselect treeview. It is treated as a wrapper around the win32 native treeview control. I would like to avoid the Treeview's Checkbox property if possible. Any suggestions is greatly appreciated!
Im gonna assume you're trying to avoid check boxes. Here is an example:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
treeView1.DrawMode = OwnerDrawText;
treeView1.DrawNode += treeView1_DrawNode;
treeView1.NodeMouseClick += treeView1_NodeMouseClick;
}
private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) {
// Show checked nodes with an underline
using (SolidBrush br = new SolidBrush(e.Node.TreeView.BackColor))
e.Graphics.FillRectangle(br, e.Node.Bounds);
Font nodeFont = e.Node.NodeFont;
if (nodeFont == null) nodeFont = e.Node.TreeView.Font;
if (e.Node.Checked) nodeFont = new Font(nodeFont, FontStyle.Underline);
using (SolidBrush br = new SolidBrush(e.Node.TreeView.ForeColor))
e.Graphics.DrawString(e.Node.Text, nodeFont, br, e.Bounds);
if (e.Node.Checked) nodeFont.Dispose();
}
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
if (Control.ModifierKeys == Keys.Shift && e.Node.Parent != null) {
// Extend selection
bool check = false;
foreach (TreeNode node in e.Node.Parent.Nodes) {
if (node.Checked) check = true;
node.Checked = check;
if (node == e.Node) break;
}
}
else {
unselectNodes(treeView1.Nodes);
e.Node.Checked = true;
}
}
This question has been answered here but I'll briefly answer your question. While it is true that Native Treeview control does not allow multiple selection, you can derive a subclass from it and override its behaviors.
Example code:
checkNodes method:
private void checkNodes(TreeNode node, bool check)
{
foreach (TreeNode child in node.Nodes)
{
if (child.Checked == true)
{
MessageBox.Show(child.Text);
}
//MessageBox.Show(child.Text);
checkNodes(child, check);
}
}
Treeview method after check:
private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Action != TreeViewAction.Unknown)
{
if (busy) return;
busy = true;
try
{
TreeNode _node = e.Node;
checkNodes(e.Node, e.Node.Checked);
if (e.Node.Checked)
{
MessageBox.Show(e.Node.Text);
}
}
finally
{
busy = false;
}
}
}
It is not trivial to do so, however it can be done.
Skiasharp enables to manipulate touch events with the method:
private void OnTouch(object sender, SKTouchEventArgs args)
With this method I can handle only one touch point coordinates:
args.Location.X, args.Location.Y
But how can I detect multitouch event?
The Android native API for example enables you to manage two finger locations in order to detect multitouch.
How can I achieve that with SkiaSharp?
Ok, I found a solution for my question here is the code.
//Multitouch handling
Dictionary<long, SKPoint> dragDictionary = new Dictionary<long, SKPoint>();
private void OnTouch(object sender, SKTouchEventArgs e)
{
switch (e.ActionType)
{
case SKTouchAction.Pressed:
dragDictionary[e.Id] = e.Location;
break;
case SKTouchAction.Entered:
break;
case SKTouchAction.Moved:
if (dragDictionary.Keys.Count > 1)
{
dragDictionary[e.Id] = e.Location;
SKPoint? p1 = null;
SKPoint? p2 = null;
foreach (long key in dragDictionary.Keys)
{
if (p1 == null)
{
p1 = dragDictionary[key];
}
else if (p2 == null)
{
p2 = dragDictionary[key];
}
}
//MultiTouch handle
}
else
{
//SingleTouch handle
}
break;
case SKTouchAction.Released:
dragDictionary.Remove(e.Id);
break;
case SKTouchAction.Exited:
break;
}
// we have handled these events
e.Handled = true;
((SKCanvasView)sender).InvalidateSurface();
}
How to?
I tried these two methods, but none works. The first hangs, the second quits the program (without any exception).
private void ApplicationClosing1(object sender, ApplicationClosingEventArgs e)
{
MessageResult result = MessageResult.None;
if (!isClosing && IsDirty)
{
result = MessageService.ShowAsync("blah", "blah",
MessageButton.YesNoCancel, MessageImage.Warning)
.GetAwaiter().GetResult();
switch (result)
{
case MessageResult.Cancel:
e.Cancel = true;
return;
case MessageResult.Yes:
isClosing = true;
SaveAsync();
break;
default:
isClosing = true;
break;
}
}
}
and
private async void ApplicationClosing2(object sender, ApplicationClosingEventArgs e)
{
if (!isClosing && IsDirty)
{
var result = await MessageService.ShowAsync("blah","blah",
MessageButton.YesNoCancel, MessageImage.Warning);
switch (result)
{
case MessageResult.Cancel:
e.Cancel = true;
return;
case MessageResult.Yes:
isClosing = true;
await SaveAsync();
break;
default:
isClosing = true;
break;
}
}
}
You could solve it the same way as the DataWindows takes care of this. First set e.Cancel = true, then if the user answers, set an internal bool _reallyClose and don't set e.Cancel when this is true.
I am trying to re size the data grid view in windows form. There are two data grid view on my form and both are fed from the database. Is there any was I can resize the data grid view on the left so that it grows with the content length and width and the data grid view shrinks with the content.
Given below is my code
private void show_Click(object sender, EventArgs e)
{
int rowIndex = Convert.ToInt32(productGridView.SelectedRows[0].Cells[2].Value);
//IEnumerable<Supplier> supplierQuery = from supplier in newNorthWindContext.Suppliers
// where supplier.SupplierID == rowIndex
// select new {} supplier;
IEnumerable<Supplier> supplierQuery = newNorthWindContext.Suppliers.Where(supliers => supliers.SupplierID == rowIndex);
supplierDataGridView.DataSource = ((ObjectQuery)supplierQuery).Execute(MergeOption.AppendOnly);
supplierDataGridView.Columns["SupplierID"].Visible = false;
supplierDataGridView.Columns["ContactTitle"].Visible = false;
supplierDataGridView.Columns["Address"].Visible = false;
supplierDataGridView.Columns["City"].Visible = false;
supplierDataGridView.Columns["Region"].Visible = false;
supplierDataGridView.Columns["PostalCode"].Visible = false;
supplierDataGridView.Columns["ContactTitle"].Visible = false;
supplierDataGridView.Columns["Address"].Visible = false;
//supplierDataGridView.AutoResizeColumns();
supplierDataGridView.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
}
private void categoryDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
Category category = (Category)this.categoryDropDown.SelectedItem;
try
{
productGridView.DataSource = category.Products;
productGridView.Columns["SupplierID"].Visible = false;
productGridView.Columns["CategoryID"].Visible = false;
productGridView.Columns["Category"].Visible = false;
productGridView.Columns["Order_Details"].Visible = false;
productGridView.Columns["Supplier"].Visible = false;
productGridView.AllowUserToDeleteRows = true;
productGridView.AutoResizeColumns();
productGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ProductDetail_Load(object sender, EventArgs e)
{
newNorthWindContext = new NorthwindEntities();
productGridView.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
IEnumerable<Category> categoryQuery = from category in newNorthWindContext.Categories.Include("Products")
orderby category.CategoryName
select category;
try
{
this.categoryDropDown.DataSource = ((ObjectQuery)categoryQuery).Execute(MergeOption.AppendOnly);
this.categoryDropDown.DisplayMember = "categoryName";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
This solves the issue.
supplierDataGridView.Width = supplierDataGridView.Columns.GetColumnsWidth(DataGridViewElementStates.Visible)+4;
at the end of show_Click you should have something like
supplierDataGridView.Width = supplierDataGridView.Columns.Sum(x => x.Width) + supplierDataGridView.RowHeadersWidth + 2;
supplierDataGridView.Height = supplierDataGridView.GetRowDisplayRectangle(supplierDataGridView.NewRowIndex, true).Bottom + supplierDataGridView.GetRowDisplayRectangle(supplierDataGridView.NewRowIndex, false).Height;
I hope this helps!