ListBox's behavior is that the first item is selected automatically, how can I avoid that??
Note: I prefer to do this with pure xaml, if you have any code-behind ideas then please don't bother yourself.
Try
IsSynchronizedWithCurrentItem="False"
Well i tried this using FocusManager.FocusedElement .. and made the intial focus to
listbox itself.. so it has the focus..but no element is selected..
if u press down or tab ..the 1st element of the listbox will be selected...
<Window
......
FocusManager.FocusedElement="{Binding ElementName=listbox2}">
<ListBox x:Name="listbox2" HorizontalAlignment="Left"
VerticalAlignment="Bottom" Width="117.333" Height="116"
Margin="30.667,0,0,30">
<ListBoxItem>Jim</ListBoxItem>
<ListBoxItem>Mark</ListBoxItem>
<ListBoxItem>Mandy</ListBoxItem>
</ListBox>
remove IsSynchronizedWithCurrentItem="True" an add it with the next SelectionChanged event if needed.
This solved my problem
You could set SelectedIndex to -1 :
<ListBox ItemsSource="{Binding MyData}" SelectedIndex="-1"/>
Note: I want to do this with pure xaml, if you have any code-behind ideas then please don't bother yourself.
Unfortunately you can't do everything in XAML... you can usually avoid code-behind, but you still need to write converters, markup extensions or attached properties
Here's a technique I use quite often. It builds on the above example of adding the FocusedElement attribute to your Window or UserControl.
My deal is that I don't want ANY of the controls on my window to have focus. The solution for me is to create a dummy control that has no UI and assign focus to that. It just so happens that Control fits the bill perfectly:
<UserControl
x:Class="MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FocusManager.FocusedElement="{Binding ElementName=focus_thief}"
mc:Ignorable="d">
<Grid>
<!-- no renderable UI -->
<Control Name="focus_thief"/>
<!-- wants focus, but won't get it -->
<ListBox>
<ListBoxItem>First Item</ListBoxItem>
</ListBox>
</Grid>
</UserControl>
<ListBox SelectioMode="Single" SelectedIndex="-1"/>
Is SelectedIndex the property you're looking for ? Or maybe I don't get your point...
Same issue here. Anyone found a "clean" solution?
The problem is the same here, it causes a bunch of triggers to execute.
Obvious solution/fix:
Remove SelectionChanged event handlers from XAML
Add handlers in the constructor after InitializeComponents has loaded the listbox.
Add a blank item.
Related
I'm trying to change the Z order of components on my WPF canvas, but it doesn't seem to exist as a XAML property or method in the code behind.
Here's my XAML:
<UserControl x:Class="FrontendUI.Controls.RadialTracker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FrontendUI.Controls"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="500">
<Grid >
<Canvas x:Name="TrackerCanvas">
</Canvas>
</Grid>
At first I was trying to do this programmatically:
Then I tried adding a Path using XAML and setting the Canvas.ZIndex, which also didn't exist. There was the Panel.ZIndex though, but I'm assuming this is referring to something higher in the UI (the grid, or User control itself?)
Not sure how to proceed. Does anyone know why this is happening?
Canvas inherits from Panel. Panel.SetZIndex() is a static method and Panel.ZIndex is an attached property that is why you are not seeing it in the xaml.
To set ZIndex for child components in xaml.
<Canvas >
<Button Content="Button" Panel.ZIndex="1" />
</Canvas>
To set Zindex for child components in code behind.
Canvas.SetZIndex(control, index);
You said "There was the Panel.ZIndex though, but I'm assuming this is referring
to something higher in the UI (the grid, or User control itself?)"
Your Assumption is wrong. To achieve your requirement you need to set the Panel.ZIndex
You asked : But they all use Canvas.ZIndex, Does anyone know why this is happening?
Because ZIndex is an attached property (and not a regular dependency property).
I have an automation client that uses the AutomationElement.FromPoint method to get the AutomationElement under the cursor:
AutomationElement element = AutomationElement.FromPoint(point);
Typically this works great, but I keep running into a problem with certain WPF applications. The problem occurs when there is a UserControl on the same UI level as another important UI element.
For example:
<Window x:Class="wpfTestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" xmlns:c="clr-namespace:wpfTestApp">
<Window.Resources>
<c:NameList x:Key="NameListData"/>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Source={StaticResource NameListData}}"
Height="300" HorizontalAlignment="Left" Margin="10,10,0,0" Name="listBox1"
VerticalAlignment="Top" Width="153" >
</ListBox>
<UserControl Name="exampleUserControl">
<TextBlock Visibility="Hidden">Loading...</TextBlock>
</UserControl>
</Grid>
</Window>
When I attempt to point to any of the listbox items (or even the listbox itself), all I get is the "exampleUserControl".
I know that there are other methods for obtaining AutomationElements that don't depend on location, but in this case that is my only option, since we are trying to get the element under the cursor. The problem is, in this case, the important element (i.e. the listbox items) are covered up by this unimportant item ("exampleUserControl" containing "Loading..." text).
Is there any alternative to the FromPoint method, or some way that I can get it to ignore such elements?
There are several methods can find/search the Element.
You can find these interfaces on the MSDN http://msdn.microsoft.com/en-us/library/ms606809
For instance:
AutomationElement.FindFirst - http://msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.findfirst
AutomationElement.FindAll - http://msdn.microsoft.com/en-us/library/system.windows.automation.automationelement.findall
// Sample: Find the first Element and the classname = ""SciCalc"
AutomationElement calcRoot = AutomationElement.RootElement.FindFirst(TreeScope.Children,
new PropertyCondition(AutomationElement.ClassNameProperty, "SciCalc"));
"AutomationElement.RootElement" is the parent of all the currently opened windows and controls.
For improve the performance you can find the target window first and then scan the controls on the AutomationElement of the Target window.
For instance: You can find and create the target WPF window via "AutomationElement.FindFirst" or "AutomationElement.FromHandle" first and search you listbox on the target window.
The clean solution to your problem is to set Visibility="Hidden" to the UserControl instead of the TextBlock
I am trying to implement SelectAll (text) functionality for all TextBoxes in my WPF application. I found how to do that here. However, the first TextBox on my form is not automatically focused. I try to remedy that in the Window_Loaded eventhandler by simply using firstTextBox.Focus. That works, but the Text property of this TextBox is set through binding and it seems that this happens after the Window_Loaded event. So, I end up with a first textbox that is initially focused, but has not its Text selected. It seems I need to hook up to a different Event. Which one?
Why don't you try DataContextChangedEvent. Bringing focus is always a pain in WPF... we have to relay on code behind file for it...
Try using FocusManager in the XAML of your window:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
FocusManager.FocusedElement="{Binding ElementName=firstTextBox}">
<Grid>
<TextBox Name="firstTextBox" />
</Grid>
</Window>
I have created a UserControl that consists of an ItemsCollection. Each item in this collection consists of a ListBox.
My application is represented by a Window, which contains this UserControl. I want to be able to manage events related to items inside the ListBox. How can I achieve this? (I am not sure if this is relevant or not, but the UserControl is in a assembly different from the application.)
Here's the code of the UserControl:
<UserControl
x:Class="UserControls.CalendarMonthViewControl.CalendarMonthView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignWidth="580"
d:DesignHeight="300"
xmlns:calendarMonthViewControl="clr-namespace:UserControls.CalendarMonthViewControl"
Name="CalendarMonthViewControl">
<Grid>
<ItemsControl
ItemsSource="{Binding ElementName=CalendarMonthViewControl, Path=Days}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="6" Columns="7" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type calendarMonthViewControl:Day}">
<Border>
<Grid>
<ListBox ItemsSource="{Binding Path=CalendarDayItems}" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
#vlad is on the right track.
There's a couple of options here. Both of them involve handling routed events.
To handle a routed event, you use the name of the owning class followed by the name of the event.
The first option is to simply handle the selection changed events (or some other ListBox event) on the Window class:
<Window ...
ListBox.SelectionChanged="OnChildListboxSelectionChanged">
...
</Window>
The second option (more typical approach) is to handle the ListBox events inside of the UserControl and then aggregate them in some way and fire an event at that level. This event is then handled by the Window. This event could be a routed event or a standard .NET event.
<UserControl ...
ListBox.SelectionChanged="OnChildListBoxSelectionChanged">
...
</UserControl>
Code behind for user control:
public event EventHandler<MyArgTypeEventArgs> ListBoxUpdated;
private void OnChildListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// aggregate data and info
MyArgTypeEventArgs handler = ListBoxUpdated;
if (handler != null)
handler.Invoke(this, GenerateArgs());
}
The Window handles this event:
<Window ...
ListBoxUpdated="OnListBoxUpdated">
...
</Window>
This should give you something to start with.
I haven't used them much myself, but I think RoutedEvents would solve your problem. The events bubble up from your ListBox to the Window (or another element lower in the tree) where you can handle them.
edit: quoting from the link: To add a handler for an event using XAML, you declare the event name as an attribute on the element that is an event listener. The value of the attribute is the name of your implemented handler method, which must exist in the partial class of the code-behind file.
since UserControl inherits from UIElement, I'm guessing something like this would work (untested atm):
<UserControl
x:Class="UserControls.CalendarMonthViewControl.CalendarMonthView"
[...]
ListBox.NameOfEvent="EventHandlerName">
I don't think what you're trying to do is the right approach as it's creating unnecessary dependence between your views and means that your UserControl is not properly encapsulated.
In my opinion the nice solution would be to handle events in your UserControl's viewmodel and set up a relation between the viewmodel of your Window as needed, so that the views themselves are independent.
Public Sub New(ByVal log As Entities.LogSystem)
InitializeComponent()
Me.DataContext = log
End Sub
This is the the initializer for my custom control It passes in a single entity that has several property fields. This control is added to a parent control so that it appears in a stackpanel.
Anyway I am trying to get the specific data from this control into several different text boxes:
<UserControl x:Class="LogSystemPickerItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WavelengthIS.WISRED.UserControls"
Width="579" Height="122">
<UserControl.Resources>
<local:LogSystemPickerItem x:Key="Log"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource Log}}">
<Label Height="30" Name="Label1" VerticalAlignment="Top" Content="{Binding deptDescription}"/>
</Grid>
</UserControl>
As you can see i havent really gotten too far. I have tried many different ways to do this including using dependency properties...I just really cant find a tutorial that shows this specific circumstance...can anyone point me in the right direction?
If you're setting the DataContext in the code behind as per your first code snippet, there's no need to also do it in the XAML, so you can remove the "Log" resource and the corresponding DataContext assignment on the Grid.
Once you've done that, it should work assuming there is a deptDescription property on your log class.
... and in XAML you may do it this way...
<UserControl.DataContext>
<local:LogSystemPickerItem/>
</UserControl.DataContext>