Collapsed Tab Item Prevents Control Select in WPF Designer - wpf

I'm using Visual Studio Pro 2019, and I came across an issue when using the tab control. I created a test project to test switching between collapsed tabs programmatically, but found that, when in the designer, I'm unable to select the control within the tab when the tabs are collapsed. I found this answer confirming that the tab being collapsed is the issue.
My question is whether there is a fix for this that isn't just turning the tabs to visible, as it shifts the item's grid location.
The alternate solution could be to manually alternate the visibility of overlapping grids, but tabs seem to be the more appropriate solution.
xaml:
<Window x:Class="MainWindow"
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"
xmlns:local="clr-namespace:delete3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Background="#FF424242">
<Grid>
<TabControl Name="Tabs" HorizontalAlignment="Left" Height="255" Margin="122,51,0,0" VerticalAlignment="Top" Width="437">
<TabItem Name="First" Header="TabItem" Visibility="Collapsed">
<Grid Background="#FFE5E5E5">
<TextBox HorizontalAlignment="Left" Height="23" Margin="143,129,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="29"/>
</Grid>
</TabItem>
<TabItem Name="Second" Header="TabItem" Visibility="Collapsed">
<Grid Background="#FFE5E5E5">
<TextBox HorizontalAlignment="Left" Height="23" Margin="195,90,0,0" TextWrapping="Wrap" Text="2" VerticalAlignment="Top" Width="29"/>
</Grid>
</TabItem>
</TabControl>
<Button Content="1" HorizontalAlignment="Left" Margin="191,359,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<Button Content="2" HorizontalAlignment="Left" Margin="484,379,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
</Grid>

Related

How to remove element from collection at child control level

I've created UserControl for adding/removing attributes using the buttons. It has ItemsControl with ObservableCollection of attributes bound to it as a ViewModel and button for adding new attribute to collection. Each new attribute creates an entity in collection which is also a UserControl with bound attribute ViewModel and button for deleting itself.
I wanted to write this functionality so the single attribute control (and other controls) can be reusable - and I use it in a few places. Currently adding new attributes works properly, but I can't find any working way for delete button to work properly and remove object from the collection.
I tried to refer through this.Parent, but CustomAttributeControl's parent is null, I tried to refer through Tag or use Prism.Core, but I couldn't implement anything properly for this to work and I couldn't find anyone with similar nested controls problem to base on. It's easy when there is no nested control for single attribute, but here I can't come up with anything. I'm fairly new to WPF and I feel there should be an easy way to do this.
single attribute control
attribute control's XAML:
<UserControl x:Class="xxx.UI.CustomAttributeControl"
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:models="clr-namespace:xxx.ViewModels.Attributes"
mc:Ignorable="d" >
<DockPanel Width="auto" HorizontalAlignment="Stretch" Margin="0,2">
<TextBox Text="{Binding Name}" Height="20" TextWrapping="Wrap" Width="160"/>
<TextBlock Width="60"/>
<ComboBox x:Name="DataType" Height="20" Width="120" SelectionChanged="DataType_SelectionChanged"/>
<TextBlock Width="10"/>
<TextBox Text="{Binding ListValues}" x:Name="ListValues" Height="20" TextWrapping="Wrap" Width="120"/>
<DockPanel HorizontalAlignment="Right">
<CheckBox IsChecked="{Binding Visible}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="20,0"/>
<Button x:Name="Delete" Content="X" Width="22" Height="20" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="20,0"/>
</DockPanel>
</DockPanel>
</UserControl>
list control
list control's XAML:
<UserControl x:Class="xxx.UI.CustomAttributesControl"
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:xxx.UI"
mc:Ignorable="d">
<StackPanel>
<Label FontSize="20">Custom attributes</Label>
<StackPanel>
<DockPanel HorizontalAlignment="Stretch">
<Label Width="160" HorizontalAlignment="Left" HorizontalContentAlignment="Center">Attribute name</Label>
<TextBlock Width="60"/>
<Label Width="120" HorizontalAlignment="Left" HorizontalContentAlignment="Center">Attribute type</Label>
<TextBlock Width="10"/>
<Label Width="120" HorizontalAlignment="Left" HorizontalContentAlignment="Center">List values</Label>
<DockPanel HorizontalAlignment="Right">
<Label Width="60" HorizontalAlignment="Right" HorizontalContentAlignment="Center">Visible</Label>
<Label Width="60" HorizontalAlignment="Right" HorizontalContentAlignment="Center">Delete</Label>
</DockPanel>
</DockPanel>
<ItemsControl ItemsSource="{Binding}"> <!-- it's binding ObservableCollection of custom attributes from parent control -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:CustomAttributeControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<DockPanel HorizontalAlignment="Right">
<Button Margin="20,10" Click="AddAttribute">+ Add attribute</Button>
</DockPanel>
</StackPanel>
</StackPanel>
</UserControl>
Code for adding attribute in .xaml.cs:
private void AddAttribute(object sender, RoutedEventArgs e)
{
var attributes = (ObservableCollection<CustomAttribute>)DataContext;
attributes.Add(new CustomAttribute());
}

Frame Page controls layout

Could you please tell me where I have gone wrong, my frame size takes the size of the wpf window, code is:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BSP" Height="700" Width="990" WindowStartupLocation="CenterScreen">
<Grid Background="Green" VerticalAlignment="Center" HorizontalAlignment="Center" >
<Frame Name="MainFrame" Source="LoginScreen.xaml" NavigationUIVisibility="Hidden" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
</Grid>
</Window>
The page size less than the window and also the total size of margin+width+size of label is less than the size of page yet the button is being displayed as cut. Code for the page is below:
<Page x:Class="Loggedin"
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"
Height="660" Width="920"
Title="Loggedin">
<Grid Background="white" Margin="2">
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
<Label Content="Loggedin as" Height="28" HorizontalAlignment="Left" Name="Loggedinas" />
<Button Content="LogOut" Margin="780,0,0,0" Height="28" Name="Logout" Width="50" HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
</Page>
Could you please assist me, it is eating my brain from 2 days :(. Following are pics of output:
Pic from Visual Studios: http://clip2net.com/s/1Fpb7
Pic from Runtime: http://clip2net.com/s/1FpbQ
Have you thought about using a DockPanel instead of a StackPanel? It seems to be a closer fit for the layout you're trying to achieve :
<DockPanel VerticalAlignment="Top">
<Label Content="Loggedin as" Height="28" HorizontalAlignment="Left" Name="Loggedinas" />
<Button Content="LogOut" Height="28" Name="Logout" Width="50" HorizontalAlignment="Right"/>
</DockPanel>
Any time you have margins that look like Margin="780,0,0,0" it usually means you're working too hard and there's a better way to do it. In my quick scratch tests, the 780 pixel left margin was pushing the button off the frame.

Scale usercontrol in wpf?

i have multiple items in my usercontrol. I put everything in a grid. But now i am trying, if the resolution of my screen changes, the window scales automatically. This just doesn't work.
I already used viewbox, but not with the wanted result.
This is my usercontrol:
<UserControl x:Class="NewWPFVragenBeheer.Maak_toets.Views.ChangeCourse"
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:converters="clr-namespace:NewWPFVragenBeheer.Converters"
mc:Ignorable="d" d:DesignHeight="200" d:DesignWidth="700"
>
<UserControl.Resources>
<XmlDataProvider x:Key="Vakken"
Source="C:\Users\Ruben\Desktop\Stage 26-04\stage_TFW\stage_TFW\NewWPFVragenBeheer\Data\Courses.xml"
XPath="/Courses/Course"
/>
<converters:RadioBoolToIntConverter x:Key="radioBoolToIntConverter" />
</UserControl.Resources>
<Viewbox Stretch="None">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="722*" />
<ColumnDefinition Width="254*" />
</Grid.ColumnDefinitions>
<Label Content="Maximale tijd:" Height="28" FontWeight="Bold" HorizontalAlignment="Left" Margin="12,28,0,0" Name="label1" VerticalAlignment="Top" Width="177" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="215,30,0,0" Text="{Binding Path=MaxTime}" VerticalAlignment="Top" Width="145" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="215,2,0,0" Text="{Binding Path=ExamName,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Name="textBox1" VerticalAlignment="Top" Width="145" />
<Label FontWeight="Bold" Content="Punten:" Height="28" HorizontalAlignment="Left" Margin="386,0,0,0" Name="label2" VerticalAlignment="Top" />
<TextBox Height="23" Text="{Binding Path=Score,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" HorizontalAlignment="Left" Margin="567,2,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" />
<Label Content="{Binding Path= FeedbackText, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Height="28" HorizontalAlignment="Right" Margin="0,153,527,0" Name="label3" VerticalAlignment="Top" Width="200" Foreground="#FFF50D0D" />
</Grid>
</Viewbox>
</UserControl>
this usercontrol is set in a window:
<Window x:Class="NewWPFVragenBeheer.MaakToetsDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:NewWPFVragenBeheer.Views"
Title="MaakToetsDialog"
WindowStyle ="SingleBorderWindow"
WindowState ="Maximized"
WindowStartupLocation="CenterScreen"
>
<view:MaakToetsView />
</Window>
¨please someone help.
Set the Grid to a fixed Width and Height, and set ViewBox.Stretch to Uniform. That should do it.
The correct answer likely is more complicated than the solution you seek, but I'll try to keep it short.
To do what you want, in my experience your best bet is to use a Grid as your primary initial element and then situate your controls within that Grid (or other Grids inside of it) and wrap the individual controls in ViewBoxes. After that tie the UserControl SizeChanged event to a method that forces the height and width of the UserControl to maintain an appropriate ratio.
That's the best way I have found to handle it on my WPF UIs.

Prevent manual scrolling of a ScrollViewer

I have a ScrollViewer which wraps a bunch of dynamically created TextBox controls. The HorizontalScrollBarVisibility and VerticalScrollBarVisibility are both set to Hidden. I am programmatically scrolling the ScrollViewer in response to the user scrolling a gridview.
The problem i am having is that when the user places the focus on one of those TextBox elements and then presses the left/right arrow keys, the ScrollViewer is scrolling. I want to prevent this manual scrolling and only allow programmatic scrolling. Obviously disabling the ScrollViewer is not an option as the user needs to be able to add text to the TextBoxes inside it. Similarly, setting the HorizontalScrollBarVisibility property to Disabled doesn't work, as that resets the scroll offset back to zero.
How can i lock scrolling, or prevent manual scrolling?
By removing manual operation of the scroll bars, and hiding them, you are basically saying you want something that has a list of items, that can be scrolled from code, but is not a ListBox...
Conclusion: Don't use a ListBox :)
As you are managing the scrolling yourself, why not parent the TextBoxes under a StackPanel within a canvas (with a clipping rectangle of course). Then use the Canvas.Top/Left properties on the StackPanel to scroll it.
The example below does that. I added a slider bound to the Canvas.Top property so you can test it.
Xaml Example:
<UserControl x:Class="SilverlightApplication1.NotAListbox"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas Background="Aquamarine" HorizontalAlignment="Center" Name="canvas1" VerticalAlignment="Center" Width="200" Height="200">
<Canvas.Clip>
<RectangleGeometry Rect="0,0,200,200"></RectangleGeometry>
</Canvas.Clip>
<StackPanel Canvas.Top="{Binding ElementName=slider1, Path=Value}" Name="stackPanel1">
<TextBox Height="23" Text="textBox 1" Width="120" />
<TextBox Height="23" Text="textBox 2" Width="120" />
<TextBox Height="23" Text="textBox 3" Width="120" />
<TextBox Height="23" Text="textBox 4" Width="120" />
<TextBox Height="23" Text="textBox 5" Width="120" />
<TextBox Height="23" Text="textBox 6" Width="120" />
<TextBox Height="23" Text="textBox 7" Width="120" />
<TextBox Height="23" Text="textBox 8" Width="120" />
<TextBox Height="23" Text="textBox 9" Width="120" />
</StackPanel>
</Canvas>
<Slider Height="171" HorizontalAlignment="Center" Margin="316,62,57,66" Name="slider1" VerticalAlignment="Center" Width="27" Orientation="Vertical" Minimum="-223" Maximum="200" />
</Grid>
</UserControl>

WPF: Can't drop filename in textbox

I'm trying to drop a file into a textbox on my WPF application but it won't work. I believe I have the XAML setup correctly to do this, and a PreviewDragOver event handler does work-- just not Drop or PreviewDrop. Here's the XAML in question:
<Window x:Class="TableTagCount.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" AllowDrop="True">
<Grid Name="bgGrid" Drop="bgGrid_Drop" AllowDrop="True">
<Grid.Background>
<ImageBrush ImageSource="/TableTagCount;component/Images/Sunset.jpg" Stretch="Fill" TileMode="None" />
</Grid.Background>
<Button Content="Analyze" Height="23" HorizontalAlignment="Left" Margin="32,91,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click"/>
<TextBox Height="23" HorizontalAlignment="Left" Margin="32,43,0,0" Name="textBox1" VerticalAlignment="Top" Width="205" PreviewDragOver="textBox1_PreviewDragOver" AllowDrop="True" />
<Label Content="File Name" Height="28" HorizontalAlignment="Left" Margin="32,13,0,0" Name="label1" VerticalAlignment="Top" Width="65" />
</Grid></Window>
Note that the Drop operation does work on my Grid.
Also, I'd like to prevent the Drop event from being handled by the Grid if my textbox handles it first. In my textbox Drop handler I'm setting the DragEventArg's Handled property to true. Is this enough to keep the event from bubbling up to the Grid?
First, I don't see a Drop handler on your TextBox. Could that be the reason it doesn't work? ;-)
Second, yes, setting Handled to true should be enough to stop bubbling.

Resources