.NET/C#/WPF noob here. I'm trying to give a textbox a border based on a variable I can bind to (variable stores results of validation). My first attempt looked like this:
<Border ... Visibility="{Binding ServerName.IsValid, Converter={StaticResource BoolToVisibility}}">
<TextBox ... />
</Border>
But this had the undesired side effect of hiding the textbox within it when visibility was hidden. After that I looked at DataTriggers, but it didn't seem like what I needed. Any ideas on how I can bind the border to that variable?
Thanks!
You can layer it:
<Grid>
<Border ... /> <!-- Bind as before -->
<TextBox Margin="5"/> <!-- Margin to not completely hide border below -->
</Grid>
(You can also overlay the border by switching the order if that is preferable)
You could use a DataTrigger as well but you would need to change the appearance rather than hiding it completely.
Related
I need to create a simple user control which is used for displaying a descriptive message to the user. The XAML definition that I have for this control is as follows:
<UserControl x:Class="Console.WPF.DisplayMessageView"
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="550"
HorizontalAlignment="Stretch">
<UserControl.Resources>
<!--Converters-->
<BooleanToVisibilityConverter x:Key="BooleanToVisibility" />
</UserControl.Resources>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox
Grid.Column="0"
VerticalAlignment="Top"
FontWeight="Normal"
FontSize="10"
Padding="12,4,2,2"
Height="74"
Background="White"
BorderThickness="1"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
TextWrapping="Wrap"
Text="{Binding DetailsText, Mode=OneWay}" />
<Image Source="..."
Stretch="None"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="0,2,0,0"
Visibility="{Binding IsErrorMessage, Converter={StaticResource BooleanToVisibility}}"/>
</Grid>
</UserControl>
This UserControl is currently embedded within a sizable stack of containers (DockPanels, StackPanels, etc.) and user controls. However, it's first parent container is a DockPanel. It is the last control in the DockPanel and the LastChildFill property is set to true on the panel.
My problem is that when I use this user control, regardless of HorizontalAlignment settings, it alway sizes the user control to the size of the text field. This means that if the text field is short, the user control will be small and look odd since it's not filling it's respective content hole. If the text is a vary long block of descriptive text, it doesn't wrap and continues to expand and is hidden off the edge of the screen.
I can't figure out how to fix this. I also want to note that this application does not use scroll bars, which have been band from use, except on list boxes. I can't use scroll regions for this application, however, this message object absolutely must expand to fill the container but NOT expand any larger.
How can I accomplish this without constraining a fixed Width value on my user control instance? Instead, I need the user control to grow with the container, when the window grows as well.
NOTE
I'm adding the C# tag, just in case this has to involve a code-behind change. I really hope it's just a matter of setting the right set of magic-properties, which have eluded me, however, I'm not opposed to encoding a rock-solid code behind solution, so long as it specifically does what I need it to do.
I'm trying to get a ContentControl to apply a ContentThemeTransitionwhere the content will be a string, so when the string changes via a binding the new string will animate in. I can't use ContentThemeTransition with a TextBlock as this doesn't derive from ContentControl.
Here is some example XAML that shows the problem. If I edit the text in the Textbox (which represents the text in my ViewModel that the ContentControl is really bound to) I would expect the Text shown in the ContentControl to animate in, but it doesn't.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" x:Name="text" Text="Hello" Width="100" Height="30"/>
<ContentControl Grid.Row="1" Width="100" Height="100" Content="{Binding ElementName=text , Path=Text}">
<ContentControl.Transitions>
<TransitionCollection>
<ContentThemeTransition HorizontalOffset="40"/>
</TransitionCollection>
</ContentControl.Transitions>
</ContentControl>
</Grid>
What am I doing wrong?
Update
I am getting somewhere now. If you replace the ContentControl XAML to
<ContentPresenter Background="Black" Foreground="Red" Grid.Row="1" Width="100" Height="100" Content="{Binding ElementName=text , Path=Text}">
<ContentPresenter.ContentTransitions>
<TransitionCollection>
<ContentThemeTransition VerticalOffset="-100"/>
</TransitionCollection>
</ContentPresenter.ContentTransitions>
</ContentPresenter>
then it works. Oddly, with the VerticalOffset =-100 as above the new value animates down outside of the ContentControli.e. its visible outside the bounds of the control. Anyone know how to change things so the animation only appears within the confines of the ContentPresenter?
Tested by my side, your first <ContentThemeTransition HorizontalOffset="40"/> and second <ContentThemeTransition VerticalOffset="-100"/> both work but only for the first time, you can enlarge the HorizontalOffset for testing and check if it works.
Since you expected that the animation should work every time the text is changed, I think you will need to create a animation which targets the Text of TextBlock directly instead of targeting the Content of ContentControl.
In this scenario, XAML Behaviors will be a good helper. You can refer to #Jerry Nixon - MSFT's answer in thread: How to animate TextBlock when its value changes in WinRT XAML?
Update:
My mistake that I only noticed that you changed HorizontalOffset to VerticalOffset. You actually also changed ContentControl to ContentPresenter.
According to the UI coordinate of UWP, since your animation target the ContentPresenter, then consider the left-top point of your ContentPresent is (0, 0). When you set <ContentThemeTransition VerticalOffset="-100"/>, it will transit from up (0, -100) back to (0, 0) and it will definitely animate outside of your ContentPresent, I think it is designed to be so, and we're not able change it. Here I can only suggest that modifying the transition from down to up like <ContentThemeTransition VerticalOffset="100"/>, it will help a little here but eventually it changes your animation, so I don't think this will be a good approach.
I was trying to follow this instruction on how to do it, but I'm just starting out with WPF.
How do I do this using a UserControl that i can reuse in different TabControls?
Also which one is the "Header" ContentPresenter in the TabControl Style?
Below is the instruction found at
https://github.com/MahApps/MahApps.Metro/issues/281
The other way is to modify/create a style - the issue then is hooking
it up to an actual 'close' event in a generic fashion.
If you look at the TabControl style, you'll see the "Header"
ContentPresenter. If you wrap that in a stackpanel and add a button
like so:
<StackPanel Orientation="Horizontal">
<Label x:Name="root" FontSize="26.67">
<ContentPresenter ContentSource="Header" RecognizesAccessKey="True" />
</Label>
<Button Content="X" />
</StackPanel>
You get :
If you have that in your Window or UserControl (rather than a resource
dictionary), you can wire that up so Click can fire and you can then
remove the item from the databound collection or directly from the
TabControl.
The easiest way is to use the MetroTabItem. It comes with the property CloseButtonEnabled to enable/disable the close button. You can also bind a command to the CloseTabCommand and CloseTabCommandParameter.
<TabControl xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls">
<Controls:MetroTabItem Header="The Header of the TabItem"
CloseButtonEnabled="True"
CloseTabCommand="{Binding CloseTabCommand}"
CloseTabCommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Header}">
<!-- your content of the TabItem -->
</Controls:MetroTabItem>
</TabControl>
Hope this helps.
I got a problem with the design of my WPF program. My XAML looks like this:
<StackPanel Orientation="{Binding Orientation}">
<Border ... />
<Border ... />
<Border ... />
<Border Margin="2"
VerticalAlignment="Stretch"
CornerRadius="3"
Padding="4">
<WrapPanel>
<TextBlock VerticalAlignment="Center"
Text="Time Range:"
Width="66" />
<controls:WinFormsWrapper EndDateTime="{Binding EndDateTime,Mode=TwoWay}"
InitialEndDateTime="{Binding InitialEndDateTime}"
InitialStartDateTime="{Binding InitialStartDateTime}"
StartDateTime="{Binding StartDateTime,Mode=TwoWay}"/>
</WrapPanel>
</Border>
<Border ... />
</StackPanel>
Inside The WrapPanel you can see there is my WinFormsWrapper. In my Viewmodel i got a property Orientation which will determine how to Orientate the StackPanel. I want the WrapPanel now to fill the whole control horizontally if the Orientation is set to vertical and vice versa.
Does anyone know a good way to do this?
EDIT:
The Type of the property is System.Windows.Controls.Orientation and the possible values are: System.Windows.Controls.Orientation.Vertical and System.Windows.Controls.Orientation.Horizontal.
If you set a Background to your WrapPanel the panel is full size.
I think that you should use a DockPanel instead of your WrapPanel with the property value LastChildFill="True".
Your error comes from invalid values. Set a valid start value to your Orientation property
private Orientation orientation = Orientation.Horizontal;
I'm applying EntranceThemeTransition to StackPanel that contains bunch of controls. When I show a popup everything works fine except TextBlocks that jump a little after animation.
Here is a video of that:
http://screencast.com/t/VXSiti6Mh
Here is code I'm using:
<StackPanel Margin="40">
<StackPanel.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition FromHorizontalOffset="100" />
</TransitionCollection>
</StackPanel.ChildrenTransitions>
<TextBlock Text="Filter Results" />
<TextBlock >Show</TextBlock>
</StackPanel>
The popup itself has PaneThemeTransition set as it's Transition.
Any ideas why it could be happening?
Have you tried:
UseLayoutRounding="True" SnapsToDevicePixels="True"
on the container.
I found a workaround - wrap each textblock with StackPanel. Clearly it's not ideal but it works.
I still wonder if there is a way to fix it without hacks...