I am making myself a project manager and I need to refresh Project List every so often. When I am refreshing the Project Manager, I want to select the item that was previously selected. But that selection causes my text box to unselect, therefore, what happens is that that text box unselects after typing one key.
So outline what happens:
I try to edit one text box
Edition causes update in project -> program calls RefreshProjectList()
RefreshProjectList() on marked position causes selected text box to unselect
Result: You must select text box after writing one symbol
Picture if useful
These selected text boxes are struggling to be edited
Code:
private void RefreshProjectList() {
if (BlockListReload)
return;
Project selected = (Project)ProjectList.SelectedItem;
ProjectList.Items.Clear();
CurrentlyShown.Clear();
foreach(Project p in Projects){
if (p.state == State.Planned && ShowPlanned.Checked) {
CurrentlyShown.Add(p);
ProjectList.Items.Add(p);
}
if (p.state == State.Active && ShowActive.Checked) {
CurrentlyShown.Add(p);
ProjectList.Items.Add(p);
}
if (p.state == State.Finished && ShowFinished.Checked) {
CurrentlyShown.Add(p);
ProjectList.Items.Add(p);
}
if (p.state == State.Delayed && ShowDelayed.Checked) {
CurrentlyShown.Add(p);
ProjectList.Items.Add(p);
}
}
if (selected == null)
return;
if (ProjectList.Items.Contains(selected)) {
ProjectList.SelectedItem = selected; // IF I REMOVE THIS
} else {
if (ProjectList.Items.Count > 0)
ProjectList.SelectedIndex = 0; // OR THIS LINE, EVERYTHING WORKS
}
}
If you need more code, I will be happy to provide, but I don't want to spam you with loads of unuseful code.
Q: Why does changing selected item in ListBox cause deselecting of TextBox and how to prevent it?
Several controls that have selectable text or items also come with a property HideSelection.
This includes:
TextBox
RichTextBox
ListView
but not
ListBox
CheckedListBox
DataGridView
Like it or not it always defaults to true so the selection is hidden whenever the focus is off the control..
Simply set it to false in the designer and you can see all selection no matter where the focus is..
OMG. I honestly don't know why I did not see it.
ProjectList.SelectedItem = selected;
//where ProjectList is ListBox<Project> and selected is Project
I am selecting an item in the ProjectList(ListBox). I didn't realize that it was calling a ProjectList_SelectedIndexChanged() event which was doing it.
EDIT: SOLVED by adding this:
if (focused != null) {
this.ActiveControl = focused;
focused.Select(focused.TextLength,0);
}
Where focused is a TextBox I set to last selected TextBox and this is the form.
Thanks TaW.
Related
I have a problem to reset a dropdownlist is c# I have hiden and showed dropdown's depending on a value in the first selection dropdown box my code did work but i remembered you can type in a combobox and changed it to dropdownlist in visual studio and after that nope not working anymore. so basically i don't want the items to be removed from list it must just be at the starting "empty value" like it was when program loaded here is the code that worked before the change
if(serviceFault_cb.Text == "Report Fault")
{
serviceType_cb.Text = "";
serviceType_cb.Hide();
serviceType_lb.Hide();
faultMain1_lb.Show();
faultMain1_cb.Show();
}
else if (serviceFault_cb.Text == "Service and Faults")
{
serviceType_cb.Show();
serviceType_lb.Show();
faultMain1_lb.Show();
faultMain1_cb.Show();
}
else
{
serviceType_cb.Show();
serviceType_lb.Show();
faultMain1_cb.Text = "";
faultMain1_lb.Hide();
faultMain1_cb.Hide();
}
a basic if statement to hide and show combobox's just need the value to clear when box is hidden and loaded again
Add an empty item into each combobox that would work as a deselected value.
Add it before you add the actual items, then you can deselect a value by doing
serviceType_cb.SelectedIndex = 0;
panel_erviceType.Show();
Also I'd suggest using a panel to encapsulate the combobox with it's corresponding label to hide them simultaneously.
I am generating x amount of buttons and I give all of them a unique name.
After all those are generated, I want to edit one of them without regenerating them so I was wondering if I could get a component by its name?
I am using WinForms
Yes:
Control myControl = Controls.Find("textBox1");
Now, beware that you have to do proper casting hen found, because Find returns a control.
You can use Controls property of your form (or some container control on your form). With LINQ you can select buttons and then find first button with required name:
var button1 = Controls.OfType<Button>().FirstOrDefault(b => b.Name == "button1");
Or if you want to search child controls recursively
var button1 = Controls.Find("button1", true)
.OfType<Button>()
.FirstOrDefault();
Without LINQ you can use method Find(string key, bool searchAllChildren) of ControlCollection:
Control[] controls = Controls.Find("button1", true);
if (controls.Length > 0)
{
Button button1 = controls[0] as Button;
}
Button btn1 = (Button)(Controls.Find("btnName"));
This will get the required button and will save the button attributes into a new Button btn1
After all those are generated, I want to edit one of them without
regenerating them so I was wondering if I could get a component by its
name?
var myButton = Controls.Find("buttonName", true).FirstOrDefault(); //Gets control by name
if(myButton != null)
{
if (myButton.GetType() == typeof(Button)) //Check if selected control is of type Button
{
//Edit button here...
}
else
{
//Control isn't a button
}
}
else
{
//Control not found.
}
Make sure you add a reference to: linq.
I have a ComboBox in a WPF application which contains a list and 'OK' button. I would like the ComboBox popup area to be closed when a user click on the OK button which in the ComboBox.
(I want the click event to change the property: IsDropDownOpen of the ComboBox
How can I cause an internal content to close its container?
You could try replacing the Button with a ToggleButton and bind the ToggleButton.IsChecked property to the ComboBox.IsDropDownOpen property using and 'inverse bool Converter' (a Converter class that returns the opposite of the bool input value.)
The only problem with this is that you would need to 'un-toggle' the ToggleButton each time the ComboBox drop down opened.
You could use the Logical/Visual Tree to get the containing ComboBox:
DependencyObject prop = sender as DependencyObject;
while (prop != null && !(prop is ComboBox))
{
prop = LogicalTreeHelper.GetParent(prop);
}
if (prop != null)
{
((ComboBox) prop).IsDropDownOpen = false;
}
Of course thats just a quick and dirty solution and should be cleaned up. ;)
I have a page with two controls on it, a datagrid and a dataform.
In the datagrid, I have a list of all the objects of a certain class. When a user selects an item in the datagrid, the dataform is loaded with the selected object.
dataForm.CurrentItem = view.CurrentItem;
view is a PagedCollectionView which contains only the selected item.
My problem is, when setting the dataform's currenitem property, if I use just the PagedCollectionView (view) without .CurrentItem, I lose the validation on the dataform. All the required fields are not seen as required. If I use the pcv.CurrentItem as my dataform's CurrentItem validation works fine, but then another issue arrises.
When I use the PagedCollectionView's current item as the dataform's current item:
A user selects an item in the datagrid and the object is loaded fine in the dataform. If a user changes a certain value in any of the textfields on the dataform and then selects a different item to load the dataform with, the following error is thrown:
"Cannot change currency when an item has validation errors or it is being edited and AutoCommit is false. Set ItemsSource to a ICollectionView to manage currency instead."
I am not using the paging properties of the dataform and I have my own save button on the form.
I would appreciate any help, this is my first silverlight project that I am working on.
Edit- I used dataform.CommitEdit when changing the dataform's currentitem. One thing that this did not resolve is if there is a validation error on the form, the currency error is thrown. Is there anyway to bypass this. AutoEdit is true and AutoCommit is false for the dataform
It's a bit hard to determine exactly what's going on here without a sample, but here's an observation that may help resolve the problem. Try instead to bind the ItemsSource property of both the DataGrid and the DataForm to the collection view, and don't bind the DataForm's CurrentItem property. They're magically kept in sync (the selected item in the DataGrid will set the current item in the DataForm) - this is a feature of the CollectionView. This may or may not solve your problem, but either way it won't hurt :).
Blatant self promotion: this and other features of the CollectionView are covered in my book Pro Business Applications with Silverlight 4 :).
I had this problem a lot of times. And always in case add new item.
After few frustrating days I downloaded source codes of Silverlight toolkit.
(You could find in Programs FIles directory (Mine were is C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10\Source) )
Compile and reference instead of assembly System.Windows.Controls.Data.DataForm.Toolkit
In Debug mode we see strange behavior in DataForm.cs:
private static void OnCurrentItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DataForm dataForm = d as DataForm;
if (dataForm != null && !dataForm.AreHandlersSuspended())
{
if (dataForm._lastItem != null && dataForm.ShouldValidateOnCurrencyChange)
{
dataForm.ValidateItem();
}
if ((!dataForm.AutoCommitPreventsCurrentItemChange && dataForm.IsItemValid) &&
(e.NewValue == null ||
dataForm._collectionView == null ||
dataForm._collectionView.Contains(dataForm.CurrentItem)
))
{
dataForm.SetUpNewCurrentItem();
dataForm.GenerateUI(true /* clearEntityErrors */, true /* swapOldAndNew */);
dataForm.UpdateCurrentItem();
SetAllCanPropertiesAndUpdate(dataForm, false /* onlyUpdateStates */);
dataForm._lastItem = dataForm.CurrentItem;
dataForm.OnCurrentItemChanged(EventArgs.Empty);
}
else
{
dataForm.SetValueNoCallback(e.Property, e.OldValue);
throw new InvalidOperationException(string.Format(Globalization.CultureInfo.InvariantCulture, System.Windows.Controls.Data.DataForm.Toolkit.Resources.DataForm_CannotChangeCurrency, "AutoCommit", "ItemsSource", "ICollectionView"));
}
}
}
dataForm._collectionView.Contains(dataForm.CurrentItem) returns false even the same object exists in dataForm._collectionView
I changed conditional:
if ((!dataForm.AutoCommitPreventsCurrentItemChange && dataForm.IsItemValid) &&
(e.NewValue == null ||
dataForm._collectionView == null ||
dataForm._collectionView.Contains(dataForm.CurrentItem) ||
dataForm.CurrentItem == e.NewValue
))
And DataForm started work fine. Without exception and mistakes.
private void DataForm_EditEnding(object sender, DataFormEditEndingEventArgs e)
{
if (e.EditAction == DataFormEditAction.Commit)
{
...
}
else
{
DataForm1.ValidationSummary.Errors.Clear();
}
}
Check for any validation error when you are binding the current item, if you have any then clear them BindingItem.ValidationErrors.Clear(); then bind the item to dataform.
I would need to know how to let the programatically selected node make graphically in the state "selected" like the user clicked on it. SelectedNode only makes this one internally selected. Thank you very much!
The reason it does not show as highlighted is due to the tree view not having focus. This is in a button click event on my test form:
TreeView1.SelectedNode = TreeView1.Nodes(2);
TreeView1.Focus();
Which highlights the node properly. if you remove the Focus(); call it doesn't highlight until you click into the tree view (anywhere in the tree view, not necessarily on to the node that you want to be selected).
TreeView1.SelectedNode.BackColor = SystemColors.HighlightText; // This will work
Above solutions will only set the focus on it but will not change the highlight view of it.
This works for me for .net 3.5:
Set the treeview component's DrawMode property to: OwnerDrawAll
Then in the DrawNode event write the following:
if (((e.State & TreeNodeStates.Selected) != 0) && (!MyTreeView.Focused))
e.Node.ForeColor = Color.Blue;
else
e.DrawDefault = true;
And in the BeforeSelect event have:
if (MyTreeView.SelectedNode != null)
MyTreeView.SelectedNode.ForeColor = Color.Black;
e.Node.ForeColor = Color.Blue;
I don't know if it helps you or not but check the taborder of the the page and make sure that the tree view control has tab order of 0
Here is what I got to work:
void myProcedure()
{
// Hookup a DrawMode Event Handler
this.myTV.DrawNode += myTV_DrawNode;
// Set DrawMode and HideSelection
this.myTV.DrawMode = TreeViewDrawMode.OwnerDrawText;
this.myTV.HideSelection = false;
// Make sure the TreeView has Focus
this.myTV.Focus();
// Make sure the TreeView is Selected
this.myTV.Select();
// If the TreeView has a Node, I want to select the first Node to demonstrate.
if (this.myTV.Nodes.Count > 0)
{
// Make sure the node is visible
this.myTV.Nodes[0].EnsureVisible();
// Make sure the Node is Selected
this.myTV.SelectedNode = myTV.Nodes[0];
}
// Make sure the SelectedNode IS the Node that we programmatically want to select.
textBox1.Text = this.myTV.SelectedNode.Text;
// if we display sanityCheck1 string, it actually is the correct node.text
// Make sure .NET runtime knows the Node is selected
textBox1.Text += " is Selected = " + this.myTV.SelectedNode.IsSelected.ToString();
}
Following up: laalto answered the How to HighLight the TreeView.Node. The following code in the DrawNode Event Handler, from samball's answer, properly highlights the TreeView.Node based on its Selected State.
private void myTV_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
// first, let .NET draw the Node with its defaults
e.DrawDefault = true;
// Now update the highlighting or not
if (e.State == TreeNodeStates.Selected)
{
e.Node.BackColor = SystemColors.Highlight;
e.Node.ForeColor = SystemColors.HighlightText;
}
else
{
e.Node.BackColor = ((TreeView)sender).BackColor;
e.Node.ForeColor = ((TreeView)sender).ForeColor;
}
}
Platform = C# .NET 4.5 in Windows 10, Visual Studio 2015
TreeView1.SelectedNode = TreeView1.Nodes(2);
this.ActiveControl = TreeView1;
This works for me (.net 4.7)
The underlying Win32 control supports this (think it's TVIS_DROPHILITED), but I can't see the same functionality exposed through the TreeView control.
As theraneman says, you could fake it with the TreeNode.ForeColor and BackColor properties...
I had an similar issue and wanted to have a TreeView node selected (highlighted) on form load.
Maybe someone has the same problem, too.
I first tried Pondidum's solution. Without success.
But then I found the solution in another thread: Simply set the TabIndex of the TreeView to 0.
In that case you don't need to set the focus. Just choose the node that should be selected by using SelectedNode and set the TabIndex. That's it.
Not sure, but can you not change the background color of that node?