I am using the PropertyGrid from the Xceed WPF Extended Toolkit. Is there a way that I can make all properties expanded by default? Actually, I'll never need them to be "unexpanded" ever, so if the "un-expansion" (is there a word for that, BTW?) could be disabled, that would be even better.
If you are still looking for a way to do this, I just figured it out myself.
private void PropertyGrid_SelectedObjectChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
var grid = sender as PropertyGrid;
foreach (PropertyItem prop in grid.Properties)
{
if (prop.IsExpandable) //Only expand things marked as Expandable, otherwise it will expand everything possible, such as strings, which you probably don't want.
{
prop.IsExpanded = true; //This will expand the property.
prop.IsExpandable = false; //This will remove the ability to toggle the expanded state.
}
}
}
If you set IsCategorized="False" you will see all properties expanded by default:
<xceed:PropertyGrid IsCategorized="False" SelectedObject="{Binding}"/>
Also you can specify
ShowPreview="False" ShowSearchBox="False" ShowSortOptions="False"
ShowSummary="False" ShowTitle="False" ShowAdvancedOptions="False"
to disable all other parts than main property editor grid.
_propertyGrid.ExpandAllProperties();
Related
I have a combobox embedded in a toolstrip - a ToolStripCombobox instance.
The list of items is the list of values of an enum.
I'd like to be able to load/save the selection (One of the Selected[Index|Item|Text|...] properties, from/to the app's Settings "mechanism".
Ideally, I'd like to be able to do that from the designer.
Normally, hooking a control's property to a certain setting is done (in the designer) from the control's properties, under (ApplicationSettings) - but none of the SelectedXXX properties shows up in there.
FWIW, in the particular case of toostrip-bound combo-boxes, the actual SelectedXXX properties are actually found a bit deeper, at toolStripComboInstance.ComboBox.SelectedXXX.
What I have done so far is configure the binding in code:
m_runTypeCombo //the toolstrip control
.ComboBox //the actual combobox
.DataBindings.Add(
new System.Windows.Forms.Binding(
"SelectedItem",
global::JavaPad.Properties.Settings.Default,
"RunType",
true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged
)
);
The above works, but I was hoping for something cleaner (i.e. designer-based). If the built-in ToolStripCombobox doesn't support this, is there a (simple) way to derive my own type from that, and expose the SelectedXXX properties in such a way that it works with the Application Settings infrastructure (and its support in the designer)?
If you are willing to wrap the TooltipComboBox in your own custom control, you can do it like this:
public class MyCombo : ToolStripComboBox
{
[SettingsBindable(true)]
public int SelectedIndex
{
get { return ComboBox.SelectedIndex; }
set { ComboBox.SelectedIndex = value; }
}
}
Note that I haven't tested this beyond confirming that I can add the control to the ToolStrip, and that I can select a property - You may need to add PropertyChanged Events to make it work fully.
In my Winforms application I have a ToolStripMenuItem with nested sub-items, the structure of which is shown below.
File
.+...Add As....+.....File
............................Folder
............................Root Folder
Under 'Add As' I want to be able to programmatically enable and disable 'File', 'Folder', and 'Root Folder' as required. How can I access these nested items in code?
I have tried ToolStripMenuItem.DropDownItems[0].Enabled = true\false; but this affects 'Add As' and everything below it in the menu hiearachy.
If I use an index greater than zero in the code above I get an 'index out of range' error. How do I go about achieving this functionality?
Simply reference the sub-items by their own names eg:
FileToolStripMenuItem.Enabled = false;
FolderToolStripMenuItem.Enabled = false;
RootFolderToolStripMenuItem.Enabled = false;
Unless I'm missing something, this seems like the simplest answer.
As Hans' hinted in his comment, you are referencing the wrong DropDownItems collection.
To do this using indexes will get ugly quickly.
It's simpler to just reference the parent menu and loop through "its" menu collection:
private void toggleMenu_Click(object sender, EventArgs e) {
foreach (ToolStripMenuItem toolItem in addAsToolStripMenuItem.DropDownItems) {
toolItem.Enabled = !toolItem.Enabled;
}
}
Here is the ugly method, which would be difficult to maintain if you decided later to rearrange your menu structure:
foreach (ToolStripMenuItem toolItem in ((ToolStripMenuItem)((ToolStripMenuItem)menuStrip1.Items[0]).DropDownItems[0]).DropDownItems) {
toolItem.Enabled = !toolItem.Enabled;
}
I am developing an application in which two datagridviews are being populated from different data sources. I would like to have a single vertical scroll-bar that will make both gridviews work at the same time (scroll up and down together)
can anyone tell me how or direct me to a good tutorial.
If you have dgv1 and dgv2, you can create something like
dgv1.Scroll += new System.Windows.Forms.ScrollEventHandler(dgv1_Scroll);
Then, in dgv1_Scroll method, you can use FirstDisplayedScrollingRowIndex property:
dgv2.FirstDisplayedScrollingRowIndex = dgv1.FirstDisplayedScrollingRowIndex
Of course, if dgv's have different ammount of rows, you need to avoid IndexOutOfRange exception by checking each dgv rows count.
Use HorizontalScrollingOffset (or VerticalScrollingOffset).
this.dataGridViewDataSample.HorizontalScrollingOffset
I believe you can set up an event-like scenario, where whenever scrollbar A's "value" changes, change scrollbar B to the appropriate value as well.
(Note that value is a property of a scroll bar, I do not mean the value of the data inside the container.)
Please see the following msdn article regarding that property of a scroll bar for better reference:
http://msdn.microsoft.com/en-us/library/system.windows.forms.scrollbar.value.aspx
And the class itself --
http://msdn.microsoft.com/en-us/library/system.windows.forms.scrollbar.aspx
You could put the DataGridViews in Panels and use this:
public Form1()
{
InitializeComponent();
panel1.Scroll += new ScrollEventHandler(panel1_Scroll);
}
void panel1_Scroll(object sender, ScrollEventArgs e)
{
panel2.AutoScrollPosition = new Point(0,e.NewValue);
}
Unfortunately it does not seem that DataGridView has this property.
http://www.xs4all.nl/~wrb/Articles_2010/Article_DataGridViewScroll_01.htm
This link shows exactly what I needed and worked fine for me. The only problem I have now is that the datagrids does not have same rows in it. So even when one finishes (no more to scroll) the other must be able to continue.
Any suggestions?
take a look at this. i wanted to sync two listviews when i scroll any of them. u can achieve this using custom controls. code works like a charm.
_dataGridViewInput.Scroll += new ScrollEventHandler(_dataGridViewInput_Scroll);
_dataGridViewOutput.Scroll += new ScrollEventHandler(_dataGridViewOutput_Scroll);
void _dataGridViewInput_Scroll(object sender, ScrollEventArgs e)
{
this._dataGridViewOutput.FirstDisplayedScrollingRowIndex = this._dataGridViewInput.FirstDisplayedScrollingRowIndex;
}
void _dataGridViewOutput_Scroll(object sender, ScrollEventArgs e)
{
this._dataGridViewInput.FirstDisplayedScrollingRowIndex = this._dataGridViewOutput.FirstDisplayedScrollingRowIndex;
}
How do I make a tab manager that doesn't show the tab headers?
This is a winforms application, and the purpose of using a tab manager is so the display content can only be changed through code. It's good for menus where various menu options change the screen contents.
Hiding the tabs on a standard TabControl is pretty simple, once you know the trick. The tab control is sent a TCM_ADJUSTRECT message when it needs to adjust the tab size, so we just need to trap that message. (I'm sure this has been answered before, but posting the code is easier than searching for it.)
Add the following code to a new class in your project, recompile, and use the CustomTabControl class instead of the built-in control:
class CustomTabControl : TabControl
{
private const int TCM_ADJUSTRECT = 0x1328;
protected override void WndProc(ref Message m)
{
// Hide the tab headers at run-time
if (m.Msg == TCM_ADJUSTRECT && !DesignMode)
{
m.Result = (IntPtr)1;
return;
}
// call the base class implementation
base.WndProc(ref m);
}
}
(Code sample originally taken from Dot Net Thoughts.)
Note that this will not work properly for tab headers positioned on the sides or the bottom. But not only does that just look weird, you won't be able to see the tabs at run-time anyway. Just put them on the top where they belong.
Right, if it's web application, you can build your own DIV with the same placement and hide/show as per your needs.
Along with everybody else, I find your question a bit confusing. I've used this method found here before. Using this way you have a single property you can change as to whether you want to show the tab headers or not.
After the edit and comments made the question more clear, I think the normal way to handle this is to use multiple panels rather than tabs.
I guess, that using panels is the simplest solution. In addition, I suggest using my (free, opensource) VisualStateManager to simplify switching and eliminate lots of .Enabled = true horrors.
Package is available on Nuget.
Just write this code:
// Contains and propagates information about current page
private SwitchCondition<int> settingPageCondition;
// Controls state of specific controls basing on given SwitchCondition
private VisualStateSwitchController<int> settingPageController;
// (...)
private void InitializeActions()
{
// Initialize with possible options
settingPageCondition = new SwitchCondition<int>(0, 1);
settingPageController = new VisualStateSwitchController<int>(
null, // Enabled is not controlled
null, // Checked is not controlled
settingPageCondition, // Visible is controller by settingPageCondition
new SwitchControlSet<int>(0, pGeneral), // State 0 controls pGeneral
new SwitchControlSet<int>(1, pParsing)); // State 1 controls pParsing
}
// (...)
public void MainForm()
{
InitializeComponent();
InitializeActions();
}
// (...)
// Wat to set specific page
settingPageCondition.Current = 0;
I have a small problem that has been annoying me for some hours.
In my WinForms (.NET 3.5) application I create some ComboBoxes (DropDownStyle = DropDown) in a TableLayoutPanel at runtime and fill it with strings. The ComboBoxes are configured to resize automatically (Anchor = Left | Right).
The problem is that whenever the ComboBoxes are resized (i.e. the dialog is resized), the editbox portion of the ComboBox gets selected/highlighted entirely. In my opinion this creates a very confusing effect for the customer which I want to avoid.
The problem doesn't appear if the ComboBox has a fixed size.
Also note that changing the DropDownStyle is not an option - I need the possibility to enter text manually.
I already tried messing around with overriding the OnPaint method, which didn't quite work.
I also tried clearing the selection in the ComboBox.Resize event, which worked in a way, but seemed like a very ugly solution - there was a lot of flicker, intentionally selected text became deselected and I would have to add the event handler to each and every ComboBox on my dialog.
Is there a better solution to this problem?
Thank you in advance.
Regards,
Andy
This is an old question, but I found it searching for an answer and ended up implementing my own solution. Might as well post it here, right?
foreach (var cb in Controls.OfType<ComboBox>())
{
cb.Resize += (sender, e) => {
if (!cb.Focused)
cb.SelectionLength = 0;
};
}
intentionally selected text became deselected
This WinForms bug doesn't affect selected ComboBoxes, so by ignoring the ones with Focus, we take care of the problem of losing current selections.
I would have to add the event handler
to each and every ComboBox on my
dialog.
Taken care of by the foreach loop. Put it in InitializeComponent() or your .ctor if you don't want to break the designer, or have the designer break this.
there was a lot of flicker
I'm only seeing flicker if I resize very fast, but I'm on Win7 so it might be different on XP.
This appears to be a bug in the native Windows implementation of ComboBox with DropDownStyle of DropDown.
The fix detailed in the other answers here (setting the SelectionLength property to 0 (zero) in the ComboBox's Resize event) works well most of the time.
However, I found that even that fix to work around this bug does not always work. If the ComboBox is in a TableLayoutPanel, and if that TableLayoutPanel has more than one column with a Percent Size Type, then that fix often does not work.
A picture is worth a thousand words. See the following screen shot of a form I made to demonstrate the problem.
Worked for me to change the selectionLength to 0 when the WM_WINDOWPOSCHANGED gets called.
Works even with the tableLayoutPanel set to %.
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if(m.Msg == 0x0047) { // WM_WINDOWPOSCHANGED = 0x0047
if (SelectionLength != 0) {
SelectionLength = 0;
}
}
}
Wow. Thank you guys!
Apparently this bug has persisted many years.
I'm building a UserControl with .Net 4 (Visual Studio 2010).
Here's is my slightlty modified version of bsneeze's code.
Cheers
using System.Windows.Forms;
using System.Linq;
public MyUserControlCtor()
{
InitializeComponent();
foreach( Control ctrl in Controls)
{
ComboBox cb = ctrl as ComboBox;
if (cb != null)
{
cb.Resize += (sender, e) =>
{
if (!cb.Focused)
this.FCHZ_ComboBox.SelectionLength = 0;
};
}
}
}
None of the answers so far worked for me. The only reliable method I have found was to post a message asynchronously via BeginInvoke that sets SelectionLength back to zero after all other activity on the control has completed. The amount of flicker is very annoying and unprofessional, but it is the best I could come up with...so far.
internal class FixedComboBox : ComboBox
{
protected override void OnResize(EventArgs e)
{
if (IsHandleCreated && !Focused)
{
BeginInvoke((Action)(() =>
{
SelectionLength = 0;
}));
}
base.OnResize(e);
}
}
I found setting the selection length to 0 for the combo-box on the resize event of whatever control the combo-box is on causes a lot less flickering instead of doing it on the resize of the combo itself.
I actually achieved this in VB.Net but it should apply the same to C#.
Handle the Resize event for the ComboBox's parent container. Put this line in there:
MyComboBox.SelectionLength = 0
An Example (VB, obviously):
Private Sub MyControl_Resize(sender As Object, e As EventArgs) Handles Me.Resize
MyComboBox.SelectionLength = 0
End Sub
Good Luck to you!
--BP
For a ComboBox inside a TableLayoutPanel setting the .SelectionLength = 0 on the ComboBox.Resize event does not work, but doing this on the TableLayoutPanel.Resize event does:
Private Sub TableLayoutPanel_Resize(sender As Object, e As EventArgs)
Dim curr_panel = TryCast(sender, System.Windows.Forms.TableLayoutPanel)
For Each curr_combo As ComboBox In curr_panel.Controls.OfType(Of ComboBox)
If ((Not curr_combo.Focused) And curr_combo.DropDownStyle = ComboBoxStyle.DropDown) Then
curr_combo.SelectionLength = 0
End If
Next
End Sub
dim panel as new TableLayoutPanel with {
...
}
AddHandler panel.Resize, AddressOf TableLayoutPanel_Resize