Add Custom Control To ComboBox - combobox

Hi All
I create a custom User control and I want this custom control placed inside a combo box.
I'm using this code:
public class UserControlComboBox : ComboBox, IMessageFilter
{
public readonly NimaDatePickerUC.MiladiNimaDatePickerUC UserControl = new NimaDatePickerUC.MiladiNimaDatePickerUC();
protected override void WndProc(ref Message m)
{
if ((m.Msg == 0x0201) || (m.Msg == 0x0203))
{
if (DroppedDown)
HideUserControl();
else
ShowUserControl();
}
else
{
base.WndProc(ref m);
}
}
public bool PreFilterMessage(ref Message m)
{
// intercept mouse events
if ((m.Msg >= 0x0200) && (m.Msg <= 0x020A))
{
if (this.UserControl.RectangleToScreen(this.UserControl.DisplayRectangle).Contains(Cursor.Position))
{
// clicks inside the user control, handle normally
return false;
}
else
{
// clicks outside the user controlcollapse it.
if ((m.Msg == 0x0201) || (m.Msg == 0x0203))
this.HideUserControl();
return true;
}
}
else return false;
}
public new bool DroppedDown
{
get { return this.UserControl.Visible; }
}
protected void ShowUserControl()
{
if (!this.Visible)
return;
this.UserControl.Anchor = this.Anchor;
this.UserControl.BackColor = this.BackColor;
this.UserControl.Font = this.Font;
this.UserControl.ForeColor = this.ForeColor;
// you can be cleverer than this if you need to
this.UserControl.Top = this.Bottom;
this.UserControl.Left = this.Left;
this.UserControl.Width = Math.Max(this.UserControl.Width, this.Width);
this.Parent.Controls.Add(this.UserControl);
this.Parent.Controls[0].BringToFront();
this.UserControl.Visible = true;
this.UserControl.BringToFront();
base.OnDropDown(EventArgs.Empty);
// start listening for clicks
Application.AddMessageFilter(this);
}
protected void HideUserControl()
{
Application.RemoveMessageFilter(this);
base.OnDropDownClosed(EventArgs.Empty);
this.UserControl.Visible = false;
this.Parent.Controls.Remove(this.UserControl);
// you probably want to replace this with something more sensible
this.Text = this.UserControl.Text;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.UserControl.Dispose();
}
base.Dispose(disposing);
}
}
this code works well but if I'm using Combo Box inside a CONTAINER and the container smaller than comboBox size+My Custom control ,my custom control does not appear well and appear beneath the group box.
How I can show my custom control in front of all controls and containers?

This may seem intuitive but have you tried the
[controlname].BringToFront();
also found here

Related

How to avoid closing popup menu on mouse clicking in javafx combobox?

I have combobox with custom ListCell:
private class SeverityCell extends ListCell<CustomItem> {
private final CustomBox custombox;
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
custombox = new CustomBox();
}
#Override
protected void updateItem(CustomItem item, boolean empty) {
super.updateItem(item, empty);
if (null != item) {
//...
}
setGraphic(custombox);
}
}
and
combobox.setCellFactory(new Callback<ListView<CustomItem>, ListCell<CustomItem>>() {
#Override public ListCell<CustomItem> call(ListView<CustomItem> p) {
return new SeverityCell();
}
});
When I click on mu custom component popup closes, but I want to avoid it. Which method/event I need to override?
ComboBox internally utilizes ListView for rendering its items. Also its skin class is ComboBoxListViewSkin. In a source code of this class there is boolean flag to control popup hiding behavior:
// Added to allow subclasses to prevent the popup from hiding when the
// ListView is clicked on (e.g when the list cells have checkboxes).
protected boolean isHideOnClickEnabled() {
return true;
}
which is used on listview:
_listView.addEventFilter(MouseEvent.MOUSE_RELEASED, t -> {
// RT-18672: Without checking if the user is clicking in the
// scrollbar area of the ListView, the comboBox will hide. Therefore,
// we add the check below to prevent this from happening.
EventTarget target = t.getTarget();
if (target instanceof Parent) {
List<String> s = ((Parent) target).getStyleClass();
if (s.contains("thumb")
|| s.contains("track")
|| s.contains("decrement-arrow")
|| s.contains("increment-arrow")) {
return;
}
}
if (isHideOnClickEnabled()) {
comboBox.hide();
}
});
So the behavior you want can be (and probably should be) implemented with custom skin. However, the workaround can be
combobox.setSkin( new ComboBoxListViewSkin<CustomItem>( combobox )
{
#Override
protected boolean isHideOnClickEnabled()
{
return false;
}
} );
and manually hide the popup, when the value is changed for instance:
combobox.valueProperty().addListener( new ChangeListener()
{
#Override
public void changed( ObservableValue observable, Object oldValue, Object newValue )
{
combobox.hide();
}
});
Note please, I didn't fully test this anonymous inner skin approach.

Popup and ComboBox binding with Silverlight

I have a problem regarding the comportment my ComboBox.
First I use a combobox to display all elements in a IEnumarale.
Then, with a button wich open a popup, the user can add an alement to that list.
The problem is that when the user validate his choice and close the popup, the element is not automatly added to the ComboBox without doing a refresh of the page.
The combobox is coded as follows :
<telerik:RadComboBox x:Name="MyElements"
SelectionChanged="MyElements_OnSelectionChanged"
ItemTemplate="{StaticResource ComboBoxElementsTemplate}"
ItemsSource="{Binding ListElements}"/>
The constructor of the list is :
public IEnumerable<Element> ListElements
{
get { return _listElements; }
set
{
_listElements= value;
RaisePropertyChange("ListElements");
}
}
And the code behind of the button to validate the user choice in the popup :
private ObservableCollection<HistoriqueElement> elementList = null;
private void SelectClick(object sender, RoutedEventArgs e)
{
var element= _GridList.SelectedItem as HistoriquePasserelle;
if (_GridList.SelectedItem != null)
{
var installation = this.DataContext as Installation;
if (installation != null && element!= null)
{
element.DateFin = DateTime.Now;
HistoriqueElement newElement= new HistoriqueElement()
{
Installation = installation,
ContactAction = GlobalActeurs.Current.CurrentContact,
Date = DateTime.Now,
Element = element.Element,
StatutElement = element.StatutElement ,
Owner= element.Owner,
};
elementList.Remove(element);
}
MainPage.ClosePopup();
}
}
When the user choose a new element in the list display in the popup and validate his choice, he returns to the main page, but his choice is not automatically added to the combobox.
I can post you any parts of the code.
Thank you in advance.
The method OnDataContextChanged :
public override void OnDataContextChanged(DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is Installation)
{
if (MainPage.CurrentInstallation.LastElements != null)
{
ListElements = MainPage.CurrentInstallation.LastElements;
MyElements.SelectedIndex = 0;
}
else
{
LoadOperation<Element> operation =
_context.Load(_context.GetCurrentElementsByInstallationId(MainPage.CurrentInstallation.Id));
this._busy.IsBusy = true;
operation.Completed += delegate
{
this._busy.IsBusy = false;
if (operation.ManageError())
{
ListElements = operation.Entities;
}
};
}
this.DataContext = this;
}
else
{
RaisePageTitleChanged();
if (MainPage.CurrentInstallation == null)
return;
}
if (MyElements.SelectedItem == null && MyElements.Items.Any())
{
MyElements.SelectedIndex = 0;
}
}
If the collection the ItemsSource is bound to implement INotifyCollection changed, that is, it's an ObservableCollection<>, then the combobox will be notified of any changes to the collection and you will not need to rebind or refresh, it will all be automatic.
Once you add the item to the list, bind the itemsource to the combobox, then you dont have to refersh.
MyElements.ItemsSource = ListElements

WPF closing child- closes parent-window

i have the pretty same sample as mentioned here.
Fast concluded: MainWindow closes when the last childwindow is closed.
My Problem: I couldn't solve my problems with the described solutions. I can't produce a program where it als takes place. Only in one of my bigger progs. Maybe someone has an idea or knows any further steps.
Thanks for reading - Thomas
As requested here's a bit of code:
This is the part in the MainWindow:
bool editAfterSearch = false;
Movie selectedMovie = (Movie)this.listView.SelectedItem;
Movie backup = (Movie)selectedMovie.Clone();
if (new OnlineSearchWindow().EditMovieViaOnlineSearch(ref selectedMovie, out editAfterSearch))
{
this.coverFlow.Update(selectedMovie);
}
And that's the part of the ChildWindow:
public bool EditMovieViaOnlineSearch(ref Movie preset, out bool editAfter)
{
this.exitWithOk = false;
this.editMovieAfterSearch = false;
this.tbx_SearchTerm.Text = preset.Title;
this.linkedMovie = preset;
this.ShowDialog();
editAfter = editMovieAfterSearch;
if (this.exitWithOk)
{
this.linkedMovie.CloneOnlineInformation(ref preset);
preset.Bitmap = this.linkedMovie.Bitmap;
return true;
}
else
{
return false;
}
}
Try playing with the ShutDownMode property of your App.xaml.cs. The 3 values are OnMainWindowClose, OnLastWindowClose, and OnExplicitShutdown, and the default is OnLastWindowClose
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
this.ShutdownMode = System.Windows.ShutdownMode.OnMainWindowClose;
}
}
The below code worked for me.
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (MessageBoxResult.No == (MessageBox.Show("Are you sure you want to close this?.", "ProjectName", MessageBoxButton.YesNo)))
{
e.Cancel = true;
foreach (var item in Application.Current.Windows)
{
Window window = item as Window;
if (window.Title == "PopUpWindowName")
{
window.Topmost = true;
break;
}
}
return;
}
else
{
base.OnClosed(e);
Application.Current.Shutdown();
}
}
you can try setting the child window's allowShutDown to false and then show the mainwindow. I'm assuming you will start with mainwindow's visibility set to hidden.
Application.Current.MainWindow.Visibility = System.Windows.Visibility.Visible;
this.allowShutDown = false;
The allowShutDown will be your own property which u can set to enable you have to handle the closing event.

WP7: Suppressing XNA touch input when handled by Silverlight?

I've got an XNA + Silverlight game in Mango: Mostly XNA with some Silverlight UI on top. The problem I'm having is that when you hit a button or interact with a Silverlight control, the touch information is still passed along to the XNA game loop. How do you suppress this?
Wrote up a class to do the tracking for me. After your page loads (in the Loaded handler), create this and give it the root element (so it can attach to the LayoutUpdated event). Register any controls that might overlay the game surface during play. Then just call TouchesControl and pass in the touch position to find out if you should ignore that point or not. It caches the regions of the controls and updates them when there's a layout update.
Should work for rectangular elements moving, changing size or collapsing/expanding.
public class ControlTouchTracker
{
private List<FrameworkElement> controls = new List<FrameworkElement>();
private Dictionary<FrameworkElement, ControlRegion> controlBounds = new Dictionary<FrameworkElement, ControlRegion>();
public ControlTouchTracker(FrameworkElement rootElement)
{
rootElement.LayoutUpdated += this.OnLayoutUpdated;
}
public void RegisterControl(FrameworkElement control)
{
controls.Add(control);
}
public void RemoveControl(FrameworkElement control)
{
controls.Remove(control);
controlBounds.Remove(control);
}
private void OnLayoutUpdated(object sender, EventArgs e)
{
foreach (Control control in this.controls)
{
this.RefreshControlBounds(control);
}
}
private void RefreshControlBounds(FrameworkElement control)
{
if (this.ControlIsVisible(control))
{
try
{
GeneralTransform controlTransform = control.TransformToVisual(Application.Current.RootVisual);
Point offset = controlTransform.Transform(new Point(0, 0));
this.controlBounds[control] = new ControlRegion
{
Left = (float)offset.X,
Right = (float)(offset.X + control.ActualWidth),
Top = (float)offset.Y,
Bottom = (float)(offset.Y + control.ActualHeight)
};
}
catch (ArgumentException)
{
}
}
else
{
if (this.controlBounds.ContainsKey(control))
{
this.controlBounds.Remove(control);
}
}
}
private bool ControlIsVisible(FrameworkElement control)
{
// End case
if (control == null)
{
return true;
}
if (control.Visibility == Visibility.Collapsed)
{
return false;
}
return this.ControlIsVisible(control.Parent as FrameworkElement);
}
public bool TouchesControl(Vector2 touchPosition)
{
foreach (ControlRegion region in this.controlBounds.Values)
{
if (touchPosition.X >= region.Left && touchPosition.X <= region.Right &&
touchPosition.Y >= region.Top && touchPosition.Y <= region.Bottom)
{
return true;
}
}
return false;
}
public class ControlRegion
{
public float Left { get; set; }
public float Right { get; set; }
public float Top { get; set; }
public float Bottom { get; set; }
}
}
(edit) Updated example to work with parent elements changing Visibility.
Due to the way interop with XNA works, you will always get the touch input processed both by XNA and Silverlight - to some extent, XNA gets the priority, so the Silverlight acts on top of that. What you could do, if you need to ignore specific gesture locations (e.g. where Silverlight buttons are located), you could check the gesture position:
if (TouchPanel.IsGestureAvailable)
{
if (TouchPanel.ReadGesture().GestureType == GestureType.Tap)
{
if (TouchPanel.ReadGesture().Position == new Vector2(120, 120))
{
}
}
}

Disable right click "Silverlight" popup in comboboxes

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

Resources