I seem to be having a problem with adding multiple StackPanels in a ScrollViewer. I can add the first one and it displays the data I want but when I try to add the second StackPanel is fails and brings the error "Duplication assignment to the 'Content' property of the 'ScrollViewer' object"
My front end code is like below:
<ScrollViewer VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible"
ZoomMode="Disabled"
Grid.Column="1"
Grid.Row="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<StackPanel Style='{StaticResource BlueFirstStackPanel}'>
<TextBlock Text='Facility Patient Number:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
<TextBlock Text='Patient Number:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
<TextBlock Text='Patient Support Number:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
<TextBlock Text='NHIF Number:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
<TextBlock Text='Patient National ID:'
Style='{StaticResource TextBlockStyle}' />
<TextBox Style='{StaticResource TextBoxStyle}' />
</StackPanel>
</ScrollViewer>
My C# code for the code has this in it:
public sealed class ScrollViewer : ContentControl
{
}
And the above displays very well but when I add a second StackPanel it brings an error. Any help with this?
The ScrollViewer can only have one child control. Try wrapping both StackPanels in a Grid or another StackPanel:
<ScrollViewer>
<StackPanel x:Name="ScrollViewerChild">
<StackPanel x:Name="StackPanel1">
</StackPanel>
<StackPanel x:Name="StackPanel2">
</StackPanel>
</StackPanel>
</ScrollViewer>
Related
I'm trying to achieve something like this:
As you can see there is a title "This is what I want" that is aligned with
another label
Code that I wrote:
<Grid Width="345" Height="445" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical" Margin="10">
<Label Content="How to align this to the left:" />
<StackPanel Grid.Row="1" Orientation="Horizontal" Background="#D9D9D9">
<Label Content="€" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Label Content="256,00" FontSize="38" FontWeight="Bold" />
</StackPanel>
</StackPanel>
</Grid>
</Grid>
And results of my code looks like this:
As it is possible to notice, label is not aligned to the left, looks like there is some padding or something...
And also € sign is not on a right place, I tried to achieve this like it's on first image, but everything I tried with different types of aligns (horizontal, centered) did not work..
Thanks guys
Cheers
Set the Padding of the Label to 0 or use a TextBlock. A TextBlock is more light-weight than a Label and it has no default Padding.
And you can use the Margin property to move the €-sign up a bit:
<StackPanel Grid.Row="0" Orientation="Vertical" Margin="10">
<TextBlock Text="How to align this to the left:" />
<StackPanel Grid.Row="1" Orientation="Horizontal" Background="#D9D9D9">
<TextBlock Text="€" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Bottom"
Margin="0 0 3 5"/>
<TextBlock Text="256,00" FontSize="38" FontWeight="Bold" />
</StackPanel>
</StackPanel>
Hy everyone!
I created a title template in AvalonDock 2.2 (WPF Toolkit). The problem is that the context menu of the LayoutAnchorable is only triggered when I right-click on the part of the title that contains something (and not the entire width of the anchorable).
Here is the relevant code segment I'm using now:
<ad:DockingManager x:Class="Pdn.Gui.Docking.Control.DockingSystem" ...
AnchorablesSource="{Binding Path=Panels}">
<ad:DockingManager.Resources>
<DataTemplate x:Key="DockingWindowTitleDataTemplate" DataType="{x:Type ad:LayoutContent}">
<StackPanel ToolTip="{Binding Path=Content.ToolTip}" Orientation="Horizontal" HorizontalAlignment="Stretch">
<Image MaxHeight="16" MaxWidth="16" VerticalAlignment="Center"
Source="{Binding Path=Content.IconSource, Converter={StaticResource IconToImageSourceConverter}}" />
<TextBlock Text="{Binding Path=Content.Name}" Margin="5,0,0,0" VerticalAlignment="Center"/>
<TextBlock Text="*" Visibility="{Binding Path=Content.DirtySignVisibility}" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="DockingWindowTitleGridDataTemplate" DataType="{x:Type ad:LayoutContent}">
<Grid ToolTip="{Binding Path=Content.ToolTip}" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" MaxHeight="16" MaxWidth="16" VerticalAlignment="Center"
Source="{Binding Path=Content.IconSource, Converter={StaticResource IconToImageSourceConverter}}" />
<TextBlock Grid.Column="1" Text="{Binding Path=Content.Name}" Margin="5,0,0,0" VerticalAlignment="Center"/>
<TextBlock Grid.Column="2" Text="*" Visibility="{Binding Path=Content.DirtySignVisibility}" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DefaultPanelTitle">
<TextBlock Text="{Binding Path=Content.Name}" TextTrimming="CharacterEllipsis" />
</DataTemplate>
...
</ad:DockingManager.Resources>
<ad:DockingManager.AnchorableTitleTemplate>
<StaticResource ResourceKey="DockingWindowTitleDataTemplate" />
</ad:DockingManager.AnchorableTitleTemplate>
...
</ad:DockingManager>
When I use the DefaultPanelTitle template (which is the default template of the theme) everything is fine, the context menu is triggered on the full width of the title part.
However when I use the other two templates (Image-Name-IsDirty elements), the context menu is triggered only on the beginning of the title area (and not right to the asterix).
I'm guessing I should tell the container to fill its parent container, but I can't figure out how. I used StackPanel, Grid, DockPanel (LastChildFill = "True") with HorizontalAlignment set to Stretch. What kind of container should I use?
What am I missing?
P.S.: I can only respond to your answers for another 12 hours, then I'm gone for a while (week). But I'm not abandoning this question until it's answered :) Thanks for your patience.
Well, the solution was quite simple. I wrapped the StackPanel in a Label. Now the context menu can be triggered on every pixel in the title part. The template now looks like this:
<ad:DockingManager x:Class="Pdn.Gui.Docking.Control.DockingSystem" ...
AnchorablesSource="{Binding Path=Panels}">
<ad:DockingManager.Resources>
<DataTemplate x:Key="DockingWindowTitleDataTemplate" DataType="{x:Type ad:LayoutContent}">
<Label>
<StackPanel ToolTip="{Binding Path=Content.ToolTip}" Orientation="Horizontal" HorizontalAlignment="Stretch">
<Image MaxHeight="16" MaxWidth="16" VerticalAlignment="Center"
Source="{Binding Path=Content.IconSource, Converter={StaticResource IconToImageSourceConverter}}" />
<TextBlock Text="{Binding Path=Content.Name}" Margin="5,0,0,0" VerticalAlignment="Center"/>
<TextBlock Text="*" Visibility="{Binding Path=Content.DirtySignVisibility}" VerticalAlignment="Center"/>
</StackPanel>
</Label>
</DataTemplate>
...
</ad:DockingManager.Resources>
<ad:DockingManager.AnchorableTitleTemplate>
<StaticResource ResourceKey="DockingWindowTitleDataTemplate" />
</ad:DockingManager.AnchorableTitleTemplate>
...
</ad:DockingManager>
I love simple solutions.
In my app I have page with GridView and ComboBox. I want to change GridView.ItemTemplate property according to selected item in ComboBox. How should I implement it?
btw, I know about this question, but it is quite old and it does not look like "best practice". (How visibility/invisibility of ui control affects cpu/gpu load?)
My GridView:
<GridView x:Name="gridViewMain" Grid.Row="1" SelectionMode="None" IsItemClickEnabled="True"
ItemsSource="{Binding CurrentList}" ItemTemplate="{StaticResource gridViewMainItemTemplate}"
Loaded="gridViewMain_Loaded" LayoutUpdated="gridViewMain_LayoutUpdated">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ItemClick">
<core:CallMethodAction MethodName="GridViewClick"
TargetObject="{Binding Mode=OneWay}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</GridView>
One of my templates:
<DataTemplate x:Key="gridViewMainItemTemplate">
<Grid x:Name="gridATemplate" Width="185" Height="288">
<Image x:Name="imgATemplate" Source="{Binding image_url}" Stretch="UniformToFill"
HorizontalAlignment="Center" VerticalAlignment="Center" />
<Grid Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}" VerticalAlignment="Bottom">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlockTitle" Text="{Binding title}"
TextWrapping="Wrap" Style="{StaticResource BodyTextBlockStyle}" Margin="5,0,0,0"
Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Foreground="White" FontWeight="Bold"
MaxHeight="50" />
<TextBlock x:Name="textBlockType" TextWrapping="Wrap" Style="{StaticResource BodyTextBlockStyle}"
Margin="5,0,0,0"
Grid.Column="0" Grid.Row="1" Foreground="White" Text="{Binding type}" FontWeight="Bold" />
<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
<TextBlock x:Name="textBlockProgressL" TextWrapping="Wrap"
Style="{StaticResource BodyTextBlockStyle}" FontWeight="Bold" Foreground="White"
Text="Progress:" />
<TextBlock x:Name="textBlockProgressV" TextWrapping="Wrap"
Style="{StaticResource BodyTextBlockStyle}" FontWeight="Bold" Foreground="White"
Text="{Binding watched_episodes}" Margin="10,0,0,10" />
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
Sure you can do this! In XAML you can do anything. What you cannot do is change the Template on the fly without re-rendering. Remember, this is like telling your printer to use card stock. It will obey. If you change the setting to use notebook paper, it will obey that, too. You will just have to print again since it has already printed on card stock.
There are a few ways for you to re-render a GridView. One way is to navigate away from the page and navigate back. That's not ideal sounding in your scenario. Odds are, in your scenario, you just need to reset the ObservableCollection you are using. Like this:
void Reset<T>(ObservableCollection<T> collection)
{
var original = collection.ToArray();
collection.Clear();
foreach (var item in original)
collection.Add(item);
}
Best of luck!
You'll want to use datatemplateselector
http://blogs.msdn.com/b/bryanbolling/archive/2012/12/08/how-to-control-the-datatemplateselector-in-windows-store-apps.aspx
You can create multiple itemtemplates and choose which one to display based on any condition.
You'll have to refresh the gridview whenever the selection changes.
I am using WPF MVVM with C#. I have a Scrollviewer in a UserControl and I need the following functionality that I haven't been able to work out how to do which is basically:
When an Item gets added to the content of my ScrollViewer; if the item added is not visible I would like my ScrollViewer to scroll down so that I can view my newly added Item in my ListView. I have been able to bind the selected item successfully but not sure how to make it scroll to it.
That's all there really is to it but I'm not sure how to do this. If there's any comments or questions I'll try to suitably amend the post, I've included the .xaml below
Thanks
<ScrollViewer Background="Pink" HorizontalAlignment="Left" Height="173" x:Name="ScrollViewer1" Width="560" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden">
<Grid Name="GridValuesAndpartss" VerticalAlignment="Top" Height="165">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="370" />
<ColumnDefinition Width="204" />
</Grid.ColumnDefinitions>
<ListView SelectedItem="{Binding SelectedBetmyValue, Mode=TwoWay}" ItemsSource="{Binding Values}" Name="BetValuesListView" Height="Auto" Margin="0,0,0,0" myValueMode="Single" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ListView.View>
<GridView>
<GridViewColumn Header="Price " Width="95">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="-7,0,0,0" MinWidth="95" Width="Auto">
<TextBlock Text="{Binding Path=PriceTypeCode}" Foreground="Black" FontSize="10" ToolTip="Price Type Code" />
<TextBlock Text=":" Foreground="Black" FontSize="10" ToolTip="Price Type Code" />
<TextBlock Text="{Binding Path=PriceTaken,Converter={StaticResource myValuePriceDisplayConverter}}" Foreground="Red" FontSize="10" ToolTip="Price Taken" />
<TextBlock Text="." FontSize="4" />
<TextBlock Text="{Binding Path=PriceCurrent,Converter={StaticResource myValuePriceDisplayConverter}}" Foreground="Black" FontSize="10" ToolTip="Price # Scan Time" />
<TextBlock Text="." FontSize="4" />
<TextBlock Text="{Binding Path=PriceSP,Converter={StaticResource myValuePriceDisplayConverter}}" Foreground="Green" FontSize="10" ToolTip="Price SP" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</ScrollViewer>
I would try to use here the code behind a little bit.
Give the ScrollViewer a name (like 'x:Name="MyScrolly"').
Listen to the 'SelectionChanged'-Event of ListView.
In the event handler of selection changed event (code behind) call:
MyScrolly.ScrollToBottom();
I think the new item is always at the bottom. If not try this method: 'ScrollToVerticalOffset()'.
I have a StatusBar with 4 items in it on my C# application. I basically want to float the last two StatusBarItems to the right. I've tried it by setting them both with HorizontalAlignment="Right", but that did only work for the last item.
<StatusBar Name="statusBar1" Height="23" HorizontalAlignment="Stretch"
VerticalAlignment="Bottom">
<StatusBarItem />
<StatusBarItem />
<StatusBarItem HorizontalAlignment="Right" />
<StatusBarItem HorizontalAlignment="Right" />
</StatusBar>
I started googling and I came up with the following URL:
Blogspot
Is this really the only solution for this, or is there an easier way?
You can take advantage of the fact that the default ItemsPanel for the StatusBar is the DockPanel. The DockPanel will, by default, try to fill the remaining space with the last item. So the last StatusBarItem you add to the StatusBar will fill the remainder of the space. To take advantage of this, you can simply nest StatusBarItems like this:
<StatusBar Name="statusBar1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<StatusBarItem Content="Item 1"/>
<StatusBarItem Content="Item 2" />
<StatusBarItem HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal">
<StatusBarItem Content="Item 3"/>
<StatusBarItem Content="Item 4"/>
<ProgressBar Height="15" Width="50" IsIndeterminate="True" Margin="5,0"/>
</StackPanel>
</StatusBarItem>
</StatusBar>
Note that the HorizontalAlignment of the 3rd StatusBarItem is set to Right so that it's content will be right-aligned.
Of course, you don't have to have Item 3 and Item 4 be StatusBarItems, they could be other controls, such as Buttons or ProgressBar as I've demonstrated above as well. The StatusBarItem is simply a container that wraps items in a StatusBar, similar to how a ComboBoxItem wraps items inside of a ComboBox.
The StatusBar will wrap it's contents in StatusBarItems automatically, if you don't use them, so items 1 and 2 could just as easily be TextBoxes. The primary reason to use StatusBarItems is in the case where you want to control how the StatusBarItem works, like in the 3rd StatusBarItem where it sets the HorizontalAlignment manually, rather than rely on the default.
As mentioned, the default container is DockPanel. As such, you can set as many items as needed to DockPanel.Dock="Right". Just be sure that the fill item is last.
<StatusBar>
<StatusBarItem DockPanel.Dock="Right">
<Slider Width="100" />
</StatusBarItem>
<StatusBarItem DockPanel.Dock="Right">
<Label>Zoom: 100 %</Label>
</StatusBarItem>
<StatusBarItem>
<TextBlock>Ready</TextBlock>
</StatusBarItem>
</StatusBar>
You can also set LastChildFill to false and then use DockPanel.Dock=Right just like the solution above, without having to worry about the last item consuming all the space:
<StatusBar>
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel LastChildFill="False" />
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
</StatusBar>
Another interesting way of achieving this is to replace default panel of StatusBar with Grid, which will give you far more control over the layout of items.
<StatusBar Height="30">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem Grid.Column="0">
<TextBlock Text="{Binding ProgressMessage, Mode=OneWay}" />
</StatusBarItem>
<StatusBarItem Grid.Column="1">
<ProgressBar Value="{Binding ProgressValue, Mode=OneWay}" Width="100" Height="10" />
</StatusBarItem>
<StatusBarItem Grid.Column="2">
<Ellipse Width="12" Height="12" Stroke="Gray" Fill="Red" />
</StatusBarItem>
</StatusBar>