Tôi có Hộp danh sách wpf hiển thị danh sách hộp văn bản. Khi tôi nhấp vào Textbox, lựa chọn Listbox không thay đổi. Tôi phải bấm vào bên cạnh TextBox để chọn mục listbox. Có một số tài sản tôi cần phải đặt cho Textbox để chuyển tiếp sự kiện nhấp vào Listbox?Chọn mục Hộp văn bản trong Hộp danh sách không thay đổi mục đã chọn của hộp danh sách
Trả lời
Hộp danh sách xử lý lựa chọn mục nhưng không biết về trọng tâm của hộp văn bản được nhúng bên trong. Nếu bạn muốn thay đổi lựa chọn bất cứ khi nào một hộp văn bản được tập trung đầu vào thì bạn cần phải thay đổi lựa chọn hộp danh sách theo cách thủ công, afaik.
Có một số thuộc tính tôi cần đặt cho Hộp văn bản để chuyển tiếp sự kiện nhấp vào Hộp danh sách không?
Nó không phải là một tài sản đơn giản, nhưng bạn có thể xử lý các sự kiện GotFocus
trên TextBox
của bạn, sau đó sử dụng VisualTreeHelper để tìm ListBoxItem
và chọn nó:
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
TextBox myTextBox = sender as TextBox;
DependencyObject parent = VisualTreeHelper.GetParent(myTextBox);
while (!(parent is ListBoxItem))
{
parent = VisualTreeHelper.GetParent(parent);
}
ListBoxItem myListBoxItem = parent as ListBoxItem;
myListBoxItem.IsSelected = true;
}
Tôi không hoàn toàn chắc chắn rằng bạn muốn để thiết lập lựa chọn trực tiếp như được mô tả trong câu trả lời trước bởi vì tôi nghĩ rằng nó sẽ phá vỡ đa lựa chọn và một số scenerios khác
. Bạn có thể muốn thử tạo lại một nút như dưới đây và xem điều gì sẽ xảy ra.
<Button ClickMode="Pressed" Focusable="False">
<Button.Template>
<ControlTemplate> // change the template to get rid of all the default chrome
<Border Background="Transparent"> // Button won't be clickable without some kind of background set
<ContentPresenter />
</Border>
</ControlTemplate>
</Button.Template>
<TextBox />
không bạn rất cụ thể về tình hình ban đầu của bạn. Nhưng tôi cho rằng bạn sử dụng DataBinding và một ItemTemplate. Đó là một cách dễ dàng để làm điều này, cũng như nếu người mới bắt đầu của bạn về chủ đề này. Điều này sẽ làm việc:
<ListBox ItemsSource="{Binding someDataCollection}" Name="myListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding datafield}" Tag="{Binding .}"
GotFocus="TextBox_GotFocus"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
myListBox.SelectedItem = (sender as TextBox).Tag; /* Maybe you need to cast to the type of the objects contained in the collection(bound as ItemSource above) */
}
Cách đơn giản nhất tôi đã có thể tìm thấy để làm điều này là sử dụng sự kiện PreviewMouseDown và thiết lập thuộc tính của cha mẹ templated IsSelected. Kể từ khi sự kiện xem trước bong bóng xuống, ListBoxItem sẽ xử lý sự kiện ngay sau khi người dùng nhấp vào hộp văn bản, combobox hoặc bất kỳ điều khiển nào khác mà bạn đặt sự kiện.
Một điều thú vị về điều này là bạn có thể sử dụng cùng một sự kiện cho tất cả các loại điều khiển vì chúng đều lấy được từ phần tử Khung. Ngoài ra, thiết lập IsSelected (thay vì thiết lập SelectedItem) sẽ khiến nhiều mục được chọn khi bạn đặt SelectionMode của hộp danh sách thành "Extended", có thể hoặc không thể là thứ bạn đang tìm kiếm.
ví dụ:
C# mã
private void Element_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
((sender as FrameworkElement).TemplatedParent as ListBoxItem).IsSelected = true;
}
XAML
...
<ComboBox PreviewMouseDown="Element_PreviewMouseDown"/>
<TextBox PreviewMouseDown="Element_PreviewMouseDown"/>
...
Chúng tôi sử dụng các phong cách sau đây để thiết lập một PreviewGotKeyboardFocus mà xử lý tất cả các sự kiện của điều khiển TextBox và ComboBoxes và như vậy:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
</Style>
</ListView.ItemContainerStyle>
.210
Và sau đó chúng tôi chọn hàng trong mã sau:
protected void SelectCurrentItem(object sender, KeyboardFocusChangedEventArgs e)
{
ListViewItem item = (ListViewItem) sender;
item.IsSelected = true;
}
này là câu trả lời bạn đang tìm kiếm: Selecting a ListBoxItem when its inner ComboBox is focused
+1 để trỏ đến các giải pháp thú vị khác. – rotti2
tôi đã sử dụng tương tự như giải pháp của Robert, nhưng không có mã sau (sử dụng hành vi đính kèm).
Để làm như vậy,
Đầu tiên. Tạo lớp riêng biệt FocusBehaviour:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace MyBehaviours
{
public class FocusBehaviour
{
#region IsFocused
public static bool GetIsFocused(Control control)
{
return (bool) control.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(Control control, bool value)
{
control.SetValue(IsFocusedProperty, value);
}
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusBehaviour),
new UIPropertyMetadata(false, IsFocusedPropertyChanged));
public static void IsFocusedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as Control;
if (control == null || !(e.NewValue is bool))
return;
if ((bool)e.NewValue && !(bool)e.OldValue)
control.Focus();
}
#endregion IsFocused
#region IsListBoxItemSelected
public static bool GetIsListBoxItemSelected(Control control)
{
return (bool) control.GetValue(IsListBoxItemSelectedProperty);
}
public static void SetIsListBoxItemSelected(Control control, bool value)
{
control.SetValue(IsListBoxItemSelectedProperty, value);
}
public static readonly DependencyProperty IsListBoxItemSelectedProperty = DependencyProperty.RegisterAttached(
"IsListBoxItemSelected",
typeof(bool),
typeof(FocusBehaviour),
new UIPropertyMetadata(false, IsListBoxItemSelectedPropertyChanged));
public static void IsListBoxItemSelectedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as Control;
DependencyObject p = control;
while (p != null && !(p is ListBoxItem))
{
p = VisualTreeHelper.GetParent(p);
}
if (p == null)
return;
((ListBoxItem)p).IsSelected = (bool)e.NewValue;
}
#endregion IsListBoxItemSelected
}
}
Thứ hai. Thêm một kiểu trong phần tài nguyên (kiểu của tôi được làm tròn màu đen trên tiêu điểm). Thông báo setter cho tài sản FocusBehaviour.IsListBoxItemSelected. Bạn nên tham khảo nó trong xmlns:behave="clr-namespace:MyBehaviours"
'
<Style x:Key="PreviewTextBox" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border
Margin="6,2,0,4"
BorderBrush="#FFBDBEBD"
BorderThickness="1"
CornerRadius="8"
Background="White"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
MinWidth="100"
x:Name="bg">
<ScrollViewer
x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="Background" TargetName="bg" Value="Black"/>
<Setter Property="Background" Value="Black"/><!-- we need it for caret, it is black on black elsewise -->
<Setter Property="Foreground" Value="White"/>
<Setter Property="behave:FocusBehaviour.IsListBoxItemSelected" Value="True"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
'
thứ ba. (tùy chọn, đối với tác vụ ngược lại)
Bạn sẽ gặp, nếu không có bất kỳ nhiệm vụ ngược lại nào tập trung vào TextBox khi ListBoxItem được chọn. Tôi khuyên bạn nên sử dụng một thuộc tính khác của lớp Hành vi, IsFocused. Đây là một mẫu mẫu cho ListBoxItem
, xin vui lòng nhận thấy Property="behave:FocusBehaviour.IsFocused"
và FocusManager.IsFocusScope="True"
<DataTemplate x:Key="YourKey" DataType="{x:Type YourType}">
<Border
Background="#FFF7F3F7"
BorderBrush="#FFBDBEBD"
BorderThickness="0,0,0,1"
FocusManager.IsFocusScope="True"
x:Name="bd"
MinHeight="40">
<TextBox
x:Name="textBox"
Style="{StaticResource PreviewTextBox}"
Text="{Binding Value}" />
</Border>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding IsSelected,RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
Value="True">
<Setter
TargetName="textBox"
Property="behave:FocusBehaviour.IsFocused"
Value="True" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
tôi sử dụng một handler lớp để thiết lập hành vi này. Làm theo cách này sẽ sửa tất cả các dạng xem danh sách trong ứng dụng. Tôi không biết tại sao đây không phải là hành vi mặc định.
Trong App.xaml.cs của bạn, thêm dòng sau vào OnStartup:
protected override void OnStartup(StartupEventArgs e)
{
EventManager.RegisterClassHandler(typeof (ListViewItem),
ListViewItem.PreviewGotKeyboardFocusEvent,
new RoutedEventHandler((x,_) => (x as ListViewItem).IsSelected = true));
}
Hãy chắc chắn để sử dụng TargetType thích hợp: ListViewItem, ListBoxItem hoặc TreeViewItem.
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="IsSelected" Value="true" />
</Trigger>
</Style.Triggers>
</Style>
Không hoạt động nếu
Điều này cũng có vấn đề khiến nó bị loại bỏ khi ListView mất tiêu điểm. Câu trả lời dưới đây tốt hơn từ Arcturus –
Hãy thử mã này:
foreach (object item in this.listBox1.Items) {
if (textbox1.text.equals(item.toString())) {
//show error message; break
}
}
tôi không có đủ đại diện cho bình luận, vì vậy tôi gửi bài bình luận của tôi là câu trả lời. Giải pháp của Grazer ở trên không hoạt động trong trường hợp bạn có một điều khiển khác chẳng hạn như Button
cần có SelectedItem
. Điều này là do theo số Style Trigger
, số IsKeyboardFocusWithin
trở thành sai khi bạn nhấp vào số Button
và số SelectedItem
trở thành vô giá trị.
Thảo luận cũ, nhưng có lẽ câu trả lời của tôi sẽ giúp người khác ...
Giải pháp của Ben có cùng vấn đề với giải pháp của Grazer. Điều xấu là việc lựa chọn phụ thuộc vào trọng tâm [bàn phím] của hộp văn bản. Nếu bạn có một điều khiển khác trên hộp thoại của mình (tức là một nút) tiêu điểm bị mất khi nhấp vào nút và hộp danh sách trở thành chưa được chọn (SelectedItem == null). Vì vậy, bạn có hành vi khác nhau để nhấp vào mục (bên ngoài hộp văn bản) và nhấp vào hộp văn bản. Điều này là rất tẻ nhạt để xử lý và trông rất lạ.
Tôi khá chắc chắn không có giải pháp XAML thuần túy nào cho việc này. Chúng ta cần viết mã cho điều này. Giải pháp gần với những gì Mark đề xuất.
(trong ví dụ của tôi, tôi sử dụng ListViewItem thay vì ListBoxItem, nhưng giải pháp hoạt động cho cả hai).
Mã-đằng sau:
private void Element_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var frameworkElement = sender as FrameworkElement;
if (frameworkElement != null)
{
var item = FindParent<ListViewItem>(frameworkElement);
if (item != null)
item.IsSelected = true;
}
}
với FindParent (lấy từ http://www.infragistics.com/community/blogs/blagunas/archive/2013/05/29/find-the-parent-control-of-a-specific-type-in-wpf-and-silverlight.aspx):
public static T FindParent<T>(DependencyObject child) where T : DependencyObject
{
//get parent item
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
return parent;
return FindParent<T>(parentObject);
}
Trong DataTemplate của tôi:
<TextBox Text="{Binding Name}"
PreviewMouseDown="Element_PreviewMouseDown"/>
Sau đây là một việc đơn giản hóa của @ câu trả lời của Ben mà không cần phải ghi đè lên DataTemplate. Nó thậm chí có thể được áp dụng như một kiểu tĩnh. Thử nghiệm với một ListView có chứa một GridView > GridViewColumn > TextBox
.
Ví dụ:
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Resources>
- 1. Xóa các mục đã chọn khỏi hộp danh sách
- 2. WPF Cách thay đổi màu của hộp danh sách đã chọn khi hộp danh sách mất tiêu điểm
- 3. Danh sách chọn nhiều hộp
- 4. Cách liệt kê các tệp văn bản trong thư mục đã chọn trong hộp danh sách?
- 5. Lựa chọn Hộp danh sách WPF Màu
- 6. Chọn các mục trong hộp danh sách bằng C#
- 7. Mục hộp danh sách WPF không wordwrapping
- 8. hộp danh sách; số lượng các mục được chọn
- 9. Truy cập danh sách Hộp văn bản
- 10. Làm cách nào để vẽ mục hộp danh sách đã chọn bằng màu khác?
- 11. Lấy chỉ mục của nhiều mục được chọn trong một hộp danh sách bằng Silverlight
- 12. Hiển thị danh sách hộp kiểm thay vì chọn nhiều
- 13. Tạo một chuỗi các mục được chọn trong hộp danh sách được chọn trong C#
- 14. LongListMultiSelector Căn chỉnh hộp kiểm với mục danh sách
- 15. Danh sách thả xuống MVC3 không chọn mục đã chọn
- 16. Di chuột để chọn mục trong hộp danh sách trong WPF
- 17. Sắp xếp các mục trong hộp danh sách trong C#
- 18. Hộp danh sách nhiều cột trong WPF
- 19. HTML Hộp kiểm trong danh sách lựa chọn
- 20. C#: thay đổi màu hàng của hộp danh sách?
- 21. Lưu các mục của hộp danh sách vào một tệp văn bản
- 22. Thay đổi màu văn bản trong các hộp CHỌN
- 23. Hộp cuộn có chứa danh sách Hộp kiểm trong HTML
- 24. Cách tải các mục danh sách đã chọn trong hộp danh sách chọn nhiều trong chế độ xem cập nhật trong yii?
- 25. Hộp danh sách WPF trong suốt với các mục có thể chọn
- 26. Chọn Nhiều mục trong hộp danh sách trong wpf bằng cách sử dụng C#
- 27. Sử dụng JQuery để chọn hộp kiểm trong danh sách mục phụ huynh?
- 28. Kiểu hộp danh sách Mục được chọn trên điện thoại cửa sổ
- 29. Bỏ chọn tất cả các mục trong một hộp danh sách
- 30. Bản sao hộp danh sách WPF vào clipboard
này chắc chắn dường như phương pháp tốt nhất. Tôi có một hệ thống phân cấp lồng nhau sâu sắc, ListBoxes chứa trong ListBoxes khác, và các điều khiển khác nhau chứa bên trong. Phương pháp này chỉ hoạt động, bởi vì nó chỉ sử dụng ListBoxItem và không phải là điều khiển chứa. Một thay đổi được đề xuất mặc dù - đơn giản hơn là chỉ cần chọn trực tiếp mục: item.IsSelected = true – Niall
Đề xuất tuyệt vời! Tôi đã thay đổi mã số .. – Arcturus
Grazer có câu trả lời tốt hơn bên dưới – Amsakanna