Я сейчас читаю много тем и пробовал и так далее. Я не понимаю.
Вопрос При использовании MouseCapture другие элементы управления не перемещаются. Невозможно что-то щелкнуть. Подсветка не происходит при наведении мыши. MouseCaption блокирует это. Нажав дважды, необходимо. Как избежать этого?
В основном Я создал пользовательский autocompletebox, который состоит из текстового поля для свободного ввода и раскрывающегося списка в виде текстового блока, содержащего предложенный элемент-результат при заданном вводе. Это очень похоже на стандартный ComboBox.
Из Combobox мы знаем, что когда он развернут и один щелчок где-то еще, свернутый раскрывающийся список.
Я хочу точно такое же поведение, как и в комбобоксе.
Поскольку я не первый, кто спрашивает об этом, я попробовал несколько вещей, но не получил их полностью работоспособными.
То, что я все еще пытался, и у меня не получилось.
- Добавление события
OnLostFocus
в текстовое поле не распознает щелчки мыши по элементам без фокуса. - Использование
Mous.Caption(this)
с PreviewMouseLeftButtonDown
для получения любых щелчков мыши по любому место на окне. - Да, это работает! Я могу свернуть раскрывающийся список, снова снять мышь.
- Но: заголовок мыши не позволяет мне щелкнуть другой элемент UIElement. Флажки и радиобоксы не будут переключаться. Просто наведите курсор мыши на флажок или что-то еще, этот элемент больше не выделяется. Вместо этого мне теперь нужно дважды щелкнуть, чтобы проверить текстовое поле.
- Я не могу понять, как решить эту проблему.
- Кроме того, не работало то, что когда событие захвата мыши было запущено, я не могу понять, где был сделан щелчок.
source
, а также e.OriginalSource
равны моему пользовательскому элементу управления - Возможно получить позицию мыши. Но не нашел, чтобы получить позицию моего элемента управления, связанную с позицией мыши. любые свойства возвращаемого элемента управления NaN.
- Сначала я не смог распознать разницу между
PreviewMouseLeftButtonDown
и MouseLeftButtonDown
. - Я думал, что первый, при непосредственном отпускании захвата мыши, будет вызывать событие mouseclick до его первоначального назначения без захвата мыши больше. Это не так.
- Я получил его с помощью Hittest. Это так?
Какой-то код
XAML AutoCompleteBox
<UserControl x:Class="MyProject.Wpf.Application.Control.AutoCompleteBoxControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="AutoCompleteBox"
PreviewMouseLeftButtonDown="AutoComplete_MouseLeftButtonDown">
<Grid>
<StackPanel>
<TextBox Name="AutoCompleteTextBox" Text="{Binding ElementName=AutoCompleteBox, Path=TextBoxText, Mode=TwoWay}" Height="{Binding ElementName=AutoCompleteBox, Path=TextBoxHeight}" Width="{Binding ElementName=AutoCompleteBox, Path=TextBoxWidth}" Padding="5, 3, 5, 3" KeyUp="AutoCompleteTextBoxControl_KeyUp" LostKeyboardFocus="AutoCompleteTextBox_OnLostKeyboardFocus"/>
<Popup Name="ResultStackPopup" IsOpen="True" PlacementTarget="{Binding ElementName=AutoCompleteTextBox}" Placement="Custom">
<Border Name="ResultStackBorder" Width="{Binding ElementName=AutoCompleteBox, Path=SuggestionListWidth}" Height="{Binding ElementName=AutoCompleteBox, Path=SuggestionListHeight}" BorderBrush="Black" BorderThickness="1" Visibility="Collapsed" Background="White" Margin="1,0,1,0" HorizontalAlignment="Left">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Name="ResultStack"></StackPanel>
</ScrollViewer>
</Border>
</Popup>
</StackPanel>
</Grid>
</UserControl>
актуально код позади:
//Whenever the dropdown is expanded, the mouse caption is started:
this.CaptureMouse();
событие нажатия мыши:
private void AutoComplete_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (this.IsMouseCaptured)
{
if (!this.IsMouseInBounds())
{
//Release MouseCaption
this.ReleaseMouseCapture();
//Collapse SuggestionList
var border = (this.ResultStack.Parent as ScrollViewer)?.Parent as Border;
if (border != null)
{
border.Visibility = Visibility.Collapsed;
}
}
}
}
private bool IsMouseInBounds()
{
Point point = Mouse.GetPosition(this);
// Perform the hit test against a given portion of the visual object tree.
HitTestResult result = VisualTreeHelper.HitTest(this, point);
if (result != null)
{
return true;
}
return false;
}
Редактировать
К сожалению, Popup не является (afaik) членом VisualTree. Таким образом, самый популярный для Popup не работает. Поэтому я попытался проверить положение Popup с помощью Mouse-position.
Метод TransformToAncestor должен использоваться, как все говорят. Но, похоже, это не работает должным образом:
Следующие три вызова возвращают абсолютно одинаковые точки:
Window parentWindow = Window.GetWindow(this);
Point relativePointThis = this.TransformToAncestor(parentWindow).Transform(new Point(0, 0));
Point relativePointPopup = this.ResultStackPopup.TransformToAncestor(parentWindow).Transform(new Point(0, 0));
Point relativePointBorder = this.ResultStackBorder.TransformToAncestor(parentWindow).Transform(new Point(0, 0));
Это ошибка?