I want to disable scrolling ( not hide the scroll bar but disallow scrolling altogether) when the user selects certain items in my listbox
if the user moves to a differnet item ( the criterai are not important ) then I want to re-enable scrolling
How can I do this in .NET 2.0
Override CreateParams property of ListBox class.
public class My : ListBox
{
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style &= ~0x00200000; // VScroll
return cp;
}
}
}
Add following code to test,
private void Form1_Load(object sender, EventArgs e)
{
My c = new My();
for (int i = 1; i <= 100; i++){
c.Items.Add(i.ToString());
}
this.Controls.Add(c);
}
Related
I have an WPF User control in which I create a RoutedEventHandler. I want to raise an event notifying every time its height changes:
Wpfusercontrol.designer.cs:
public partial class Wpfusercontrol: System.Windows.Controls.UserControl
{
public static readonly RoutedEvent HeightChangedEvent = EventManager.RegisterRoutedEvent(
"HeightChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Wpfusercontrol));
public event RoutedEventHandler HeightChanged
{
add { AddHandler(HeightChangedEvent, value); }
remove { RemoveHandler(HeightChangedEvent, value); }
}
private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (e.HeightChanged && HeightChangedEvent != null)
{
RaiseEvent(new RoutedEventArgs(HeightChangedEvent));
}
}
}
Then this WPF user control is hosted in an ElementHost
WindowsFormsHostControl.Designer.cs:
partial class WindowsFormsHostControl
{
private void InitializeComponent()
{
this.ElementHostFormControl = new System.Windows.Forms.Integration.ElementHost();
this.Wpfusercontrol= new Wpfusercontrol();
this.SuspendLayout();
//
// ElementHostFormControl
//
this.ElementHostFormControl.Dock = System.Windows.Forms.DockStyle.Fill;
this.ElementHostFormControl.Location = new System.Drawing.Point(0, 0);
this.ElementHostFormControl.Margin = new System.Windows.Forms.Padding(2);
this.ElementHostFormControl.Name = "ElementHostFormControl";
this.ElementHostFormControl.Size = new System.Drawing.Size(75, 78);
this.ElementHostFormControl.TabIndex = 0;
this.ElementHostFormControl.Child = this.Wpfusercontrol;
//
// WindowsFormsHostControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.ElementHostFormControl);
this.Margin = new System.Windows.Forms.Padding(2);
this.Name = "WindowsFormsHostControl";
this.Size = new System.Drawing.Size(75, 78);
this.ResumeLayout(false);
}
private System.Windows.Forms.Integration.ElementHost ElementHostFormControl;
private Wpfusercontrol Wpfusercontrol;
}
WindowsFormsHostControl.cs:
public partial class WindowsFormsHostControl: System.Windows.Forms.UserControl
{
private RoutedEventHandler heightChangedEventHandler;
public WindowsFormsHostControl()
{
InitializeComponent();
}
public WindowsFormsHostControl(RoutedEventHandler heightChangedEventHandler) : this()
{
this.heightChangedEventHandler = heightChangedEventHandler;
this.Wpfusercontrol.HeightChanged += this.heightChangedEventHandler;
}
public void SubscribeHeightChanged()
{
this.Wpfusercontrol.HeightChanged += this.heightChangedEventHandler;
}
public void UnsubscribeHeightChanged()
{
this.Wpfusercontrol.HeightChanged -= this.heightChangedEventHandler;
}
}
This WindowsFormsHostControl is embedded within an UI object called custom task pane which is kind of UI container for VSTO Outlook Add-ins. This custom task pane has a button to resize its height but it does not provide an event to catch it. So when you resize the height of that custom task pane, the height of the wpf user control changes as well, so through the routed event in the wpf user control I know when the custom task pane is resized and I catch the event.
Now from one class in my VSTO Outlook Add-in application (which in fact is a winforms app), I perform below things:
private WindowsFormsHostControl windowsFormsHostControl = null;
this.windowsFormsHostControl = new WindowsFormsHostControl(this.WpfUserControl_HeightChanged);
System.Windows.Fomrs.Timer t;
private void WpfUserControl_HeightChanged(object sender, System.Windows.RoutedEventArgs e)
{
// Dome some stuff
...
t = new System.Windows.Fomrs.Timer();
t.Tick += new EventHandler(Update);
t.Interval = 100;
t.Enable = true;
}
private void Update(object sender, EventArgs e)
{
// Some more stuf....
....
// In below lines I update the height of the custom task pane (VSTO Outlook UI object) which in turn causes the WPF user control to resize its height as well. So then, I am trying to unsubscribe from the wpf routed event, then update the height for custom task pane, and finally subscribe again to the wpf routed event. I do this to prevent routed event in wpf user control fires again.
this.windowsFormsHostControl.UnsubscribeHeightChanged();
// here I update the height for custom task pane
this.windowsFormsHostControl.SubscribeHeightChanged();
}
The problem is that it looks like the line:
this.windowsFormsHostControl.UnsubscribeHeightChanged();
is not working because the routed event in the wpf user control continues raising each time I execute the line of code between UnsubscribeHeightChanged and SubscribeHeightChanged.
So what am i doing wrong?
Im'm using winform DevExpress library.
Now need to create a control, basing on PopupContainerEdit but this control must have some behaviors like when it's focused, the popup opens and when lost focus the popup closes.
This is the code I'm using but the popup dessapears after getting focus.
public class HelpEdit : PopupContainerEdit {
private PopupContainerControl _container;
private GridControl _gridControl;
private GridView _gridView;
[DefaultValue("")]
[DXCategory("Data")]
[AttributeProvider(typeof(IListSource))]
public object Datasource {
get { return _gridControl.DataSource; }
set { _gridControl.DataSource = value; }
}
public HelpEdit() : base() {
_container = new PopupContainerControl();
this.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.Standard;
this._gridControl = new GridControl();
this._gridControl.Dock = DockStyle.Fill;
this._gridView = new GridView(_gridControl);
_container.Controls.Add(_gridControl);
_container.Size = new Size(this.Width, 250);
this.Properties.PopupControl = _container;
this.Properties.PopupControl.Size = new Size(this.Width, 250);
}
protected override void OnGotFocus(EventArgs e) {
base.OnGotFocus(e);
this.ShowPopup();
}
protected override void OnLostFocus(EventArgs e) {
base.OnLostFocus(e);
this.ClosePopup();
}
}
Your popup disappears because it closes by your code as soon as the popup container control(_container) got focus itself. You should not close popup within the OnLostFocus() override because the base.OnLostFocus method of PopupContainerEdit is already contains correct code for closing popup. Or close popup conditionally, using the following code:
protected override void OnLostFocus(EventArgs e) {
if(IsPopupOpen && !EditorContainsFocus)
ClosePopup(PopupCloseMode.Immediate);
base.OnLostFocus(e);
}
I have a WPF ListBox operating in single selection mode. I am adding drag and drop to move items around. Currently the ListBox selection responds to both left button pressed and then with mouse moves with left button down. So after I wait for the MinimumVerticalDragDistance to start a drag operation, a different item could be selected. Dragging either the unselected orginal item or dragging the new selected item is confusing. Adding 'e.Handled=true' in xxx_MouseMove or xxx_PreviewMouseMove does not do anything. Any ideas on suppressing this selection due to mouse moves with left button down?
The best kludge I came up with is to cancel the ListBox's "Selection by dragging" in the IsMouseCapturedChanged event.
public partial class MainWindow : Window
{
Rect? dragSourceGestureRect;
bool busy;
public MainWindow()
{
InitializeComponent();
listBox.ItemsSource = Enumerable.Range(1, 9);
listBox.PreviewMouseLeftButtonDown += listBox_PreviewMouseLeftButtonDown;
listBox.IsMouseCapturedChanged += listBox_IsMouseCapturedChanged;
listBox.MouseMove += listBox_MouseMove;
}
void listBox_IsMouseCapturedChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (busy)
return;
if (!listBox.IsMouseCaptured)
dragSourceGestureRect = null;
else if (dragSourceGestureRect.HasValue)
{
busy = true;
{
//tell the ListBox to cancel it's "Selection by dragging"
listBox.ReleaseMouseCapture();
//Now recapture the mouse for canceling my dragging
listBox.CaptureMouse();
}
busy = false;
}
}
void listBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var center = e.GetPosition(listBox);
dragSourceGestureRect = new Rect(
center.X - SystemParameters.MinimumHorizontalDragDistance / 2,
center.Y - SystemParameters.MinimumVerticalDragDistance / 2,
SystemParameters.MinimumHorizontalDragDistance,
SystemParameters.MinimumVerticalDragDistance);
}
void listBox_MouseMove(object sender, MouseEventArgs e)
{
if (!dragSourceGestureRect.HasValue || dragSourceGestureRect.Value.Contains(e.GetPosition(listBox)))
return;
dragSourceGestureRect = null;
var data = new DataObject(DataFormats.UnicodeText, "The Data");
DragDrop.DoDragDrop(listBox, data, DragDropEffects.Copy);
e.Handled = true;
}
}
I have a simple implementation of a ListView in WPF that allows me to select multiple items in the list by holding the mouse button and dragging over the items. However, while holding the mouse button down, when I move the mouse outside the ListView, something strange happens with the selection. Ideally, I would just want the selection to remain the same, but instead it quickly cycles through all the selected items, leaving only the last item selected.
Here's the code, have any ideas?
public class MultiSelectListView : ListView
{
private bool m_isSelectionActive;
public bool IsSelectionActive
{
get { return m_isSelectionActive; }
}
protected override DependencyObject GetContainerForItemOverride()
{
return new MultiSelectListViewItem(this);
}
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
m_isSelectionActive = true;
}
protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
{
m_isSelectionActive = false;
}
}
public class MultiSelectListViewItem : ListViewItem
{
private readonly MultiSelectListView m_parent;
public MultiSelectListViewItem(MultiSelectListView parent)
{
m_parent = parent;
}
protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
{
if (m_parent.IsSelectionActive)
IsSelected = true;
}
}
The funkiness you are experiencing happens when the mouse "drag" goes above the top of the list or below the bottom of the list. I think the behavior you set up will only work well if the selection mode is Multiple. The modifications to the MultiSelectListView below set the default selection mode to Multiple and assumes the user wants to start another selection with a left mouse click. You will still experience funkiness if the SelectionMode is set to Extended or Single in the XAML.
public class MultiSelectListView : ListView
{
private bool m_isSelectionActive;
public bool IsSelectionActive
{
get
{
return m_isSelectionActive;
}
}
protected override DependencyObject GetContainerForItemOverride()
{
return new MultiSelectListViewItem(this);
}
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (SelectionMode != SelectionMode.Single)
{
SelectedItems.Clear();
}
m_isSelectionActive = true;
}
protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e)
{
m_isSelectionActive = false;
}
public MultiSelectListView() : base()
{
SelectionMode = SelectionMode.Multiple;
}
}
Hi
I'm trying to get rid of the annoying "About Silverlight" context menu that pops up whenever you right click in a Silverlight application. I've added the usual ways:
In App.xaml
rootVisual.MouseRightButtonDown += ((s, args) => args.Handled = true);
and the same for all ChildWindows.
The problem that persist is in all "pop up"-controls like comboboxes and datepicker calender popup. There I can't get rid of it. I would like to handle the right click in a style that I can make implicit for the entire application. Is this possible? Can I solve it some other smart way?
Best
Daniel
The answer was to inherit the combobox and make a custom control like this:
public class CellaComboBox : ComboBox
{
public CellaComboBox()
{
DropDownOpened += _dropDownOpened;
DropDownClosed += _dropDownClosed;
}
private static void _dropDownClosed(object sender, EventArgs e)
{
HandlePopupRightClick(sender, false);
}
private static void _dropDownOpened(object sender, EventArgs e)
{
HandlePopupRightClick(sender, true);
}
private static void HandlePopupRightClick(object sender, bool hook)
{
ComboBox box = (ComboBox)sender;
var popup = box.GetChildElement<Popup>();
if (popup != null)
{
HookPopupEvent(hook, popup);
}
}
static void HookPopupEvent(bool hook, Popup popup)
{
if (hook)
{
popup.MouseRightButtonDown += popup_MouseRightButtonDown;
popup.Child.MouseRightButtonDown += popup_MouseRightButtonDown;
}
else
{
popup.MouseRightButtonDown -= popup_MouseRightButtonDown;
popup.Child.MouseRightButtonDown -= popup_MouseRightButtonDown;
}
}
static void popup_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
e.Handled = true;
}
with the extension method for framworkelement looking like this:
public static class FrameworkElementExtensions
{
public static TType GetChildElement<TType>(this DependencyObject parent) where TType : DependencyObject
{
TType result = default(TType);
if (parent != null)
{
result = parent as TType;
if (result == null)
{
for (int childIndex = 0; childIndex < VisualTreeHelper.GetChildrenCount(parent); ++childIndex)
{
var child = VisualTreeHelper.GetChild(parent, childIndex) as FrameworkElement;
result = GetChildElement<TType>(child) as TType;
if (result != null) return result;
}
}
}
return result;
}
}
You need to handle the DatePicker in the same way but instead of DropDownOpened and DropDownClosed you use CalenderOpened and CalenderClosed
C# Corner has an article for fixing the about popup on Silverlight 3:
Disable Context Menu in Silverlight 3 Application