No Canvas.ZIndex or SetZIndex() property on WPF Canvas - wpf

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).

Related

How to disable resizing of user control in WPF

I have Usercontrol.I want to disable its resizing.
The usercontrol is:
<UserControl x:Class="DocumentUpload"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerikGrid="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
xmlns:telerikGrid1="clr-namespace:Telerik.Windows.Controls.GridView;assembly=Telerik.Windows.Controls.GridView"
xmlns:telerikInp="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Input"
xmlns:telerikNav="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation"
xmlns:telerikData="clr-namespace:Telerik.Windows.Data;assembly=Telerik.Windows.Data"
xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Height="auto" Width="auto" MaxWidth="520">
I got to know that there is property called
ResizeMode="NoResize"
.But it is not available in UserControl.Any suugestion?
You have Width and Height set to Auto, so I guess you want to allow the control to take as much space as needed but not more.
Also, UserControl is not resizing by itself, but depends upon the layout that it's part of.
So, the quickest way to fix your issue would be to set HorizontalAlignment="Left" and VerticalAlignment="Top". But you should consider the whole layout of your application and how the UC is affected by-/affects on other components of the UI.
Then the Parent property of your UserControl is holding the Window instance. Most of times, it will be NavigationWindow. Try the below code in loaded event of your UserControl and it will work.
((NavigationWindow)this.Parent).ResizeMode = ResizeMode.NoResize

UI elements obscured from UIAutomation by UserControl

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

WPF User Control extending border class. "Does not support direct content"?

I am producing graphics for a process control system and I would like to create a system border which would visually wrap the various sub system being displayed in the process mimic. I could use a regular border for this except I want it to not only changing color reflecting system status, but also popping up small "balloons" indicating the piece of the system that is in alarm state.
I created a test project with a User Control and added a ListBox (for the balloons) and a ContentPresenter element wrapped in a border control. However, whenever I use this new control in another app, it wont allow me to add content to it. I've tried messing some with the ContentPropertyAttribute and properties of the ContentPresenter element, but I feel I am in the blind here.
<UserControl x:Class="SystemStatusBorder.UserControl1"
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:DesignHeight="300" d:DesignWidth="300">
<Canvas Height="290" Width="303">
<Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ContentPresenter/>
</Border>
<ListBox Canvas.Right="0" Canvas.Bottom="0">
<ListBox.RenderTransform>
<TranslateTransform X="20"></TranslateTransform>
</ListBox.RenderTransform>
<ListBoxItem>TagA</ListBoxItem>
<ListBoxItem>TagB</ListBoxItem>
</ListBox>
</Canvas>
</UserControl>
I don't get it. What more should it need other than just the existence of a contentpresenter? UserControl subclasses ContentControl so I would have thought the wiring was in place. Eventually, I want it to be used something like this:
<SystemBorder>
<SystemBorder.MonitoredTags>
<List of relevant tags for the specific sub system goes here>
</SystemBorder.MonitoredTags>
<regular content goes here>
</SystemBorder>
To create your own container control, you must create a new custom control (not a UserControl).
Make your new control inherit from ContentControl.
Custom Controls don't have their own XAML. Instead, they are assigned a ControlTemplate.
When you create your first Custom Control, the IDE will create a new file Themes\Generic.xaml.
This is where the template for your control is. You can modify this template to match the XAML in your question. This will support the ContentPresenter element.
I found a very good walkthrough here.

ListBox always auto selects first item

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.

DependencyProperty: VS cannot find the source for binding

I'm trying to bind the Forderground dependency property to my UIControl, so that it's drawn in the color the user wishes. Since myUiControl.Foderground autocopletes, I thought I could just bind it in the XAML file like this:
{Binding ElementName=rootControl, Path=Forderground}
When debugging VS says it cannot find the source for binding with this DependencyProperty.. but I couldn't figure out why this is.
Also how can I list all dependency properties of an object while debugging?
UPDATE: If below wasn't enough for you, try downloading this sample and looking at it.
The ElementName needs to be set as the "x:Name" of your root control and the Path needs to be set to the Property on the root element you wish to bind to. Without the name it cannot find the element you are referring to (hence the initial error) and without the Path it doesn't bind to the correct property (check your output at runtime for an error).
Try this:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid x:Name="root" Background="Green">
<Button Background="White" Margin="100">
<TextBlock Background="{Binding ElementName=root, Path=Background}" Text="TESTING TESTING"/>
</Button>
</Grid>
Can you confirm that your "rootControl" element is defined earlier in the xaml markup than your Binding holder? Usually the Bindings are bound to the earlier declared elements.
If you mean ImmediateWindow and IntelliSense usage while debugging than each dependency property metadata has usually public static access modifiers. You can for instance type "Control." and observe all the corresponding dependency properties, routed events and attached properties members.
Hope this helps.

Resources