Format text from resourceDictionary in xaml - xaml

I have a text in my resource dictionary:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="ResourceDictionaryName" Localization.Comments="$Content(DoNotLocalize)">Loc-en-EN</system:String>
<!--MainControl.xaml-->
<system:String x:Key="PersonalEmail">Please enter your email./system:String></ResourceDictionary>
and I bind it to xaml this way:
<TextBlock Text="{DynamicResource PersonalEmail}" Style="{DynamicResource TextBlockStyle}"/>
Is it possible to create style or converter, to show, for example, Please bold, and rest of the text as normal?

String itself does not support rich text format, you can use a Span to show the text.
<TextBlock>
<Span>
<Bold>Please</Bold> enter your email.
</Span>
</TextBlock>
And you can put almost anything into a ResourceDictionary and give it a key, and reference it using that key.
<Window.Resources>
<Span x:Key="PersonalEmail">
<Bold>Please</Bold> enter your email.
</Span>
</Window.Resources>
<Grid>
<TextBlock>
<StaticResource ResourceKey="PersonalEmail" />
</TextBlock>
</Grid>

Related

HorizontalTextAlignment Element in a Maui xaml file, does not change the Alignment of the text

I am currently working on a UI for an application and I want to align the following label Text automatically horizontally, so I wanted to test, how I can align text normally.
The Label Documentation of Maui state, that I have to do it with the HorizontalTextAlignment Element. I tried it several times and it worked, but here it won't:
<CollectionView Grid.Row="1" BackgroundColor="Black">
<CollectionView.ItemsSource>
<x:Array Type="{x:Type models:MessageModel}">
<models:MessageModel Message="Hallo" Created="01.01.2001 00:00:00"/>
<models:MessageModel Message="Hey na!" Created="01.01.2001 00:00:00"/>
</x:Array>
</CollectionView.ItemsSource>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:MessageModel">
<Label HorizontalTextAlignment="End" TextColor="White" Text="{Binding Created}"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
The Output is the following (And yeah I could use one Label, but I wanted to try both ways):
Edit: adding the following Element HorizontalOptions="FillAndExpand" at the label + a Background Color:
Edit2:

How to use a nested string in App.xaml static resources...?

In my App.xaml file, I have the following static resources defined...
<x:String x:Key="StaticString1">static string 1</x:String>
<x:String x:Key="StaticString2">static string 2 using {StaticResource StaticString1}</x:String>
In the content view (on another page), I want to display StaticString2 and have it automatically pull in StaticString1 but it isn't working.
I want it to say "static string 2 using static string 1" but instead it just shows a literal with the curly braces ("static string 2 using {StaticResource StaticString1}").
Is it possible to do this in static resources or do I need to use a <Label.FormattedText> with <Span>s ?
No, I don't think you can combine two strings in the xaml.
You can use <Label.FormattedText> with <Span> as you mentiond to achieve this:
<ContentPage.Content>
<StackLayout>
<Label >
<Label.FormattedText>
<FormattedString>
<Span TextColor="Black" FontSize="18" Text="{StaticResource StaticString2}"/>
<Span TextColor="Black" FontSize="18" Text=" "/>
<Span TextColor="Black" FontSize="18" Text="{StaticResource StaticString1}"/>
</FormattedString>
</Label.FormattedText>
</Label>
</StackLayout>
</ContentPage.Content>
And in App.xaml:
<x:String x:Key="StaticString1">static string 1</x:String>
<x:String x:Key="StaticString2">static string 2 using </x:String>

How to create WPF UserControl having a Canvas as the "main panel"?

I want to create a UserControl having a Canvas inside it. Then I can use it like this in XAML:
<Window ...>
<Grid>
<local:MyCanvasLikeControl>
<Path .../>
<Path .../>
<Polygon.../>
</local:MyCanvasLikeControl>
</Grid>
</Window>
I have tried some things, but always get this error: "Property Content can only be set once". I know of ControlTemplates and such, but could not find my way by reading the docs by myself.
My goal is to have an equivalent to this:
<Window ...>
<Grid ...>
<Border ....>
<Canvas ...>
<Path ...>
<Path ...>
<Polygon ...>
</Canvas>
</Border>
</Grid>
</Window>
But moving the "Border / Canvas" to a UserControl named "MyCanvasLikeControl"
It's the same type of scenario as if you to stuff a bunch of elements of any other type into a control that would produce the same error like for example;
<UserControl>
<Grid/>
<StackPanel/>
<Canvas/>
<!-- you get the idea -->
</UserControl>
It's just telling you that you need to specify a parent capable of holding your content to act as the single content of its parent, which in this case would be your control. So to fix this, it's luckily simple;
<local:MyCanvasLikeControl>
<Grid>
<Path .../>
<Path .../>
<Polygon.../>
</Grid>
</local:MyCanvasLikeControl>
Or switch Grid with Canvas or whatever you want so long as it can host children elements. Hope this helps.
EDIT:
Ok, so I think the definition of requirement may have been a bit over-complicated in its explanation. If I'm understanding you correctly then here's why you're breaking.
You have your first layer of elements that contain your UserControl, but the way you're trying to insert content into it isn't the way that works, you'll need to provide that ability by specifying how you wish to allow it to be added to your control via a ContentPresenter or ContentControl etc. So instead it would be more like this inside your external UserControl;
<Border ....>
<Canvas ...>
<ContentPresenter/> or <ContentControl/> etc.
</Canvas>
</Border>
So then you can inject that stuff in there the way you want.
<Window ...>
<Grid>
<local:MyCanvasLikeControl>
<local:MyCanvasLikeControl.Content>
<Path .../>
<Path .../>
<Polygon.../>
</local:MyCanvasLikeControl.Content>
</local:MyCanvasLikeControl>
</Grid>
</Window>
Make sense?

DataTemplate does not show result of bound children

On my MainWindow.xaml page, I have the following code which works (where MyWord is a string)
<ContentControl Content="{Binding MyWord}" />
I'm playing with DataTemplates and trying understand them. So, I want to reference a DataTemplate from within my ContentControl. The DataTemplate should contain a TextBlock which binds to my string. I updated my code
<ContentControl ContentTemplate="{StaticResource ViewsTemplate}" />
And in my ResourceDictionary I add
<DataTemplate x:Key="ViewsTemplate">
<TextBlock Text="{Binding MyWord}" />
</DataTemplate>
This produces no text on screen at all. I even tried
<ContentControl Content="{Binding MyWord}" ContentTemplate="{StaticResource ViewsTemplate}" />
and still no result on screen.
I can't work out why can any one give some advice please.
Thank you
The ContentControl still needs to have some content bound to it.
<ContentControl ContentTemplate="{StaticResource ViewsTemplate}" Content="{Binding MyWord}" />
Would work, but then you'd need to change your data template because it expects to be able to find MyWord which of course it won't be able to, so you'd want to use just {Binding} instead.
Alternatively, bind the ContentControl's Content to {Binding} - the current DataContext of its parent - and leave the template as it is.

Comboboxes in GridView are synchronized instead of bound to the value from the database

I have tried to set up combo boxes in the gridview but all the combo boxes have the same value in them instead of the value from the database. I am using entity framework and WPF. There is a parent child relationship between two tables but the source for the combo box is a separate table with names and IDs for tags. I have been looking all day. Hopefully this won't be too easy to solve.
The "Tag" Column displays the combo box. The Column "Tag ID" displays the value from the database. When I display the data the TagID Changes in diffrent rows but the Tag column is the same (the first choice) in all the rows. When I change one combo box they all change. I can't see where they are hooked together. Any assistance you can provide would be appreciated. (Buler?)
Here is the XAML
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="372" Width="675" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:my="clr-namespace:TagFinanceWPF">
<Window.Resources>
<CollectionViewSource x:Key="TransactionsViewSource" d:DesignSource="{d:DesignInstance my:Transaction, CreateList=True}" />
<CollectionViewSource x:Key="TransactionsTransactionTagsViewSource" Source="{Binding Path=TransactionTags, Source={StaticResource TransactionsViewSource}}" />
<CollectionViewSource x:Key="TagLookup" />
</Window.Resources>
<Grid DataContext="{StaticResource TransactionsViewSource}">
<ListView ItemsSource="{Binding Source={StaticResource TransactionsTransactionTagsViewSource}}" Margin="12" Name="TransactionTagsListView" SelectionMode="Single">
<ListView.ItemContainerStyle>
<Style>
<Setter Property="Control.HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Control.VerticalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn x:Name="TransactionIDColumn1" Header="Transaction ID" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Path=TransactionID}" Margin="6,-1,-6,-1" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn x:Name="TagIDColumn" Header="Tag" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox Margin="-6,-1"
ItemsSource="{Binding Source={StaticResource TagLookup}}"
DisplayMemberPath="TagName"
SelectedValuePath="TagID"
SelectedValue="{Binding TagID}"
IsReadOnly="True">
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn x:Name="TagIDColumn2" Header="Tag ID" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Path=TagID}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
The VB code is:
Class MainWindow
Dim BentleyvideoEntities As TagFinanceWPF.bentleyvideoEntities = New TagFinanceWPF.bentleyvideoEntities()
Private Function GetTransactionsQuery(ByVal BentleyvideoEntities As TagFinanceWPF.bentleyvideoEntities) As System.Data.Objects.ObjectQuery(Of TagFinanceWPF.Transaction)
Dim TransactionsQuery As System.Data.Objects.ObjectQuery(Of TagFinanceWPF.Transaction) = BentleyvideoEntities.Transactions
'Update the query to include TransactionTags data in Transactions. You can modify this code as needed.
TransactionsQuery = TransactionsQuery.Include("TransactionTags")
'Returns an ObjectQuery.
Return TransactionsQuery
End Function
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
'Load data into Transactions. You can modify this code as needed.
Dim TransactionsViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("TransactionsViewSource"), System.Windows.Data.CollectionViewSource)
Dim TransactionsQuery As System.Data.Objects.ObjectQuery(Of TagFinanceWPF.Transaction) = Me.GetTransactionsQuery(BentleyvideoEntities)
TransactionsViewSource.Source = TransactionsQuery.Execute(System.Data.Objects.MergeOption.AppendOnly)
'Load data into Tags. You can modify this code as needed.
Dim customerList = From c In BentleyvideoEntities.Tags _
Order By c.TagName
Dim custSource = CType(Me.FindResource("TagLookup"), CollectionViewSource)
custSource.Source = customerList.ToList()
End Sub
End Class
I found this while researching your issue and it sounds like the exact same issue you are experiencing.
Snippit from link:
I'm not sure if this will help, but I
was reading in Chris Sells 'Windows
Forms Binding in C#, footnote, page
482', that the data source is bound to
each combobox and is managed by a
common Binding manager which in turn
is part of a Binding Context. The
Binding amager keeps all comboboxes
synchronized to the same row in the
database. However, if each combobox
has a different Binding context, hence
a diferent Binding Manager, then the
combo boxes can show different rows
from the same data source.
Based on this second article (and the suggested solution) you would need to use the row databinding event to set up the combobox's binding so that a new instace of the binding manager is created for each row bind.