How do I bind the Header of a TextBox? - c#

In windows phone 8.1, I can bind the text in a textbox to a string resource in my Resources.resw.
How do I do the same thing for the Header="My Header" tag?
i.e. bind the Header text to another string resource in Resources.resw
<TextBox Header="My Header" Text="{Binding textboxtext}" x:Name="TextBox"/>

Same way you Bind the Text field.
<TextBox Header="{Binding myBinding}" Text="{Binding textboxtext}" x:Name="TextBox"/>
If you want to point it to a Resource then
<Page.Resources>
<x:String x:Key="myTextBoxHeader">this is a textbox header</x:String>
</Page.Resources>
<TextBox Text="{Binding textboxtest}"
Header="{StaticResource myTextBoxHeader}"></TextBox>
If you pointing to a .resw file then in most cases you will need a x:Uid like this
<TextBox x:Uid="MyLocalizeTextBox"></TextBox>
Then you need to edit the strings for the stuff you want to display, in this case your Header + Text
Look at the highlighted section very carefully, you see the pattern? It won't show up on the designer and will show up when you deploy [See Image Below]
So by now you may be wondering if you combine both methods? (one to show in the designer and one to show while deploy because you're localizing). This is actually the prefer method.
2 in 1 (Both methods)
<TextBox x:Uid="MyLocalizeTextBox"
Text="{Binding textboxtest}" Header="{StaticResource myBinding}"></TextBox>
During design time it will use your local resouces, when deploy it will use the resources in the resw file.

Related

How to bind two elements to the same property in WPF - C#

I'm using C# in a WPF application with MVVM (with Caliburn Micro framework). I'm trying to bind 2 elements (one TextBlock and one TextBox) to the same property, that resides in my model view. My property is called FirstName.
I have two options to do the binding: Binding Path=FirstName or x:Name=FirstName. When I edit the textbox, I see the changes in the textblock only if I bind in a certain way (see code). Any idea of why the other way does not work? (when I type in the textbox I don't see my textblock updates)
I've tried different mode options (two ways, one way, etc). The NotifyOfPropertyChange seems to be working.
<!-- This works -->
<TextBlock Text="{Binding Path=FirstName}"/>
<TextBox x:Name="FirstName"/>
<!-- This does not work -->
<TextBlock x:Name="FirstName"/>
<TextBox Text="{Binding Path=FirstName, Mode=TwoWay}"/>
With your second example, you need to specify UpdateSourceTrigger=PropertyChanged:
<TextBlock x:Name="FirstName"/>
<TextBox Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
Otherwise, the source is only updated when the TextBox loses focus.

How can I save text input when my textbox is in resourcedictionary?

I have 2 projects in the solution explorer. One has the resource dictionary located in the folder called "Themes". The other project is set to main startup, which has the MainWindow.xaml and MainWindow.xaml.cs. I'm just wondering if I could save whatever text I will input in the textbox coded in my resource dictionary and still there the next time I open the app
The code would like this:
<TextBox telerik:PersistenceManager.StorageId="myText"
IsEnabled="{Binding IsEnabled}"
Text="{Binding Notes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
AcceptsReturn="True"
TextWrapping="Wrap"
BorderThickness="0"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Background="{x:Null}" Foreground="White" />
I tried to merged my resourcedictionary to MainWindow.xaml, but still can't
access the textbox when I write a code behind inside the MainWindow.xaml.cs.
How should I do this? I don't have any Idea what to do.
I would appreciate any kind of help.
Use application settings to persist data between sessions for a user. See
Managing Application Settings (.NET).

Can't get custom fonts to display at runtime - Windows Phone 8.1 MVVM - FontAwesome

I am having trouble with custom fonts in my Windows Phone 8.1 MVVM app.
I am using FontAwesome icons. I have included the FontAwesome font file in my project. When I set a static control such as this, it works perfectly;
<TextBlock x:Name="txtTest" Grid.Row="3" Text="" Foreground="Black" FontSize="20" FontFamily="/Assets/Fonts/FontAwesome.ttf#FontAwesome"/>
However, what I need is for this to work dynamically. I have a Hub control on the main page of the app, with ListViews in each Hub section. These are bound to a collection of custom objects, populated from an API response. When creating the collection of objects, the code looks for a marker in the response and dynamically sets the FontAwesome icon depending on the marker.
Hub Section code:
<HubSection x:Uid="hubApproved" Header="Approved"
DataContext="{Binding MyObjects.Approved}"
d:DataContext="{Binding MyObjects.Approved}"
HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}" >
<DataTemplate>
<ListView
ItemsSource="{Binding}"
ItemTemplate="{ThemeResource ApprovedTemplate}"
IsItemClickEnabled="True"
ItemClick="ListView_ItemClick"
ContinuumNavigationTransitionInfo.ExitElementContainer="True">
</ListView>
</DataTemplate>
</HubSection>
And here is the Approved Template which binds to this:
<DataTemplate x:Key="ApprovedTemplate">
<StackPanel Margin="0,0,0,19" Background="{x:Null}" >
<TextBlock FontFamily="/Assets/Fonts/FontAwesome.ttf#FontAwesome" Text="{Binding Icon}" Foreground="Black" />
<TextBlock Text="{Binding SupplierName}" Style="{ThemeResource ListViewItemTripNameTextBlockStyle}" />
<TextBlock Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" Text="{Binding StartDate}"></TextBlock>
</StackPanel>
</DataTemplate>
The Template contains a TextBlock which binds to the Icon property of my object. This is supposed to then display the appropriate FontAwesome icon, but instead just displays the unicode of the icon:
I have tried defining the font family of the Hub control from the code behind in the view, but it has no effect:
Hub.FontFamily = new FontFamily("ms-appx:///Assets/Fonts/FontAwesome.otf#FontAwesome");
Any ideas on how to dynamically get these icons to display...? Thanks
You should be able to do it like this:
FontFamily fontFam = new FontFamily("ms-appx:///Assets/Fonts/FontAwesome.otf#FontAwesome");
and set FontFamily like this:
Hub.FontFamily = fontFam
I solved this with a workaround. The icons in my ListView will only ever be 1 of 5 possible icons. So instead of setting the unicode, I created 5 different textbox objects in the template definition, one for each icon. The unicode is static, so the dynamic aspect is instead the Visibility of each object. I created corresponding XAML Visibility properties on the custom object. After this, the style object is bound to its Visibility property, like so:
<!--Generic (shopping cart icon)-->
<TextBlock FontFamily="/Assets/Fonts/FontAwesome.otf#FontAwesome" Grid.Column="0" Text="" Style="{ThemeResource ListViewItemTripNameTextBlockStyle}"
VerticalAlignment="Center" Visibility="{Binding VisGeneric}" />
Then when I create the object collection from the API response, I set the appropriate visibility property to be Visible, according the the marker in the response.
I'd like a slightly more elegant solution than this, but essentially it works...

How to bind item values in an accordion header template

I'm trying to create a simple header template for an accordion object in silverlight 4.
I've added an image and a TextBlock to the header template of the AccordionItem. I want to hide or show the image dependant on the values entered on the page.
Because i want to bind these values directly to the actual accordion item, I've created a new type 'AccordionItemWithIcons' that simply inherits from AccordionItem but adds a couple of dependancy properties to handle this. I'm only showing a couple of those properties for brevity. :)
So, here's my accordion with my 'AccordionItemWithIcons' control. Note that the property 'CheckIsVisible' is of type 'Visibility'
<Grid x:Name="LayoutRoot">
<Controls:Accordion Height="100">
<my:AccordionItemWithIcons
x:Name="FirstItem"
Content="Content Text"
Header="Header Text"
CheckIsVisible="Collapsed"
EventSummary="Summary Text"
HeaderTemplate="{StaticResource AccordionItemHeaderTemplate1}"/>
</Controls:Accordion>
</Grid>
And here is the header template.
<DataTemplate x:Key="AccordionWithIcons_HeaderTemplate1" >
<Grid >
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<TextBlock Text="{Binding EventSummary}" />
<Image Visibility="{Binding CheckIsVisible}" Source="/Labyrinth;component/cross.png"/>
</StackPanel>
</Grid>
</DataTemplate>
Can anyone explain how I can bind the TextBlock's text and the Image's Visibility to the values set in the underlying AccordionItemWithIcons object? I've spent hours messing about with different DataContext's and sources and cannot seem to get this to work!
I don't know if helps to explain what I'm trying to achieve, but ultimately in the code behind i want to be able to say something like (shown below), to show or hide the icon in the header template.
FirstItem.CheckIsVisible = Visibility.Visible
For this, there exists a VisibilityToBooleanConverter
<BooleanToVisibilityConverter x:Key=”boolVisConverter”/>
[...]
Visibility="{Binding ElementName=anyCheckbox,
Path=IsChecked,
Converter={StaticResource boolVisConverter}}"

Control which field is displayed in the textbox part of a databound WPF ComboBox

I have a ComboBox in WPF which is databound, and has data template which controls how each of the items is displayed. I have made it so that each item is displayed with two bits of text (for the Name and Path properties) and one image (for the Icon property).
At the moment when I select an item from the ComboBox the textbox bit of the ComboBox just changes to say "TestWPF.Result" which is the name of the class which I have populated the ComboBox with.
I'm interested in one (or both) of two things:
How do I change it so that it displays the value of one of the fields there (eg. so it shows the value of the Name field rather than the name of the class)?
Is it possible get it to use the same DataTemplate there as in the list of items, so that once I have selected an item it displays in the closed ComboBox the same way as it looks in the list of items. Basically I've got a DataTemplate called ShowResults and a ComboBox which uses that template. I've also added in a separate ContentControl which I've got to show the details of the selected item in the ComboBox, but I want to get that to replace the textbox in the ComboBox.
Update:
Thanks for the first answer. I've tried using a separate ContentControl, as you've described, and it works fine. The question now is how to replace the textbox part of the ComboBox with this ContentControl. Any hints on that would be most welcome.
Also, is it possible to replace the textbox bit of the ComboBox control with a mixture of the ContentControl and a textbox, so that I can still type in the textbox to help select items from the ComboBox, but then when I close the dropdown the rest ContentControl bit will be populated with the rest of the text and the icon. Hope that makes sense - ask questions if it doesn't!
Code:
I've been asked to post my code - so here it is. I've tried to remove things that I know are definitely not relevant, but I'm not sure exactly what is relevant so when in doubt I've left things in.
<Window x:Class="TestWPF.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:TestWPF"
Title="Window1" Height="300" Width="843" Loaded="Window_Loaded">
<Window.Resources>
<DataTemplate x:Key="ShowResult" DataType="TestWPF.Result">
<StackPanel Margin="5" Orientation="Horizontal">
<Image Width="32" Height="32" Source="{Binding Path=Image}"/>
<StackPanel Margin="5">
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}"/>
<TextBlock Text="{Binding Path=Path}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid Width="786">
<Button Height="23" HorizontalAlignment="Right" Margin="0,24,166,0" Name="btnTest" VerticalAlignment="Top" Width="75" Click="btnTest_Click">Add</Button>
<ComboBox StaysOpenOnEdit="True" DropDownClosed="comboBox1_DropDownClosed" PreviewTextInput="comboBox1_PreviewTextInput" SelectionChanged="comboBox1_SelectionChanged" ItemTemplate="{StaticResource ShowResult}" Margin="259,109,22,89" Name="comboBox1" IsEditable="True" />
<ContentControl Height="50" Margin="268,0,22,21" Name="contentControl1" VerticalAlignment="Bottom" Content="{Binding ElementName=comboBox1,Path=SelectedValue}" ContentTemplate="{StaticResource ShowResult}"/>
</Grid>
You got the binding part right - binding to the data and using a DataTemplate to display the source the way you want to.
As to your second question, a way to do it would be to use a ComboBox with IsEditable="True" as you have, and withing the TextChanged event handler check if the comboBox.Items contains the new value, if not check use Linq to seach for a match:
if (comboBox.Items.Contains(e.NewValue))
return;
var matches =
with comboBox.Items
select item
where item.BeginsWith(e.NewValue);
if (matches.Count > 0)
comboBox.SelectedItem = matches.First();
Just place the Property Binding expression to the textBox,You dont need to apply template.
Another way to get exact Data template, Place a ContentControl in the place of textBox and assign the same DataTemplate (say x:Name="robinTemplate")
<ContentControl Content="{Binding ElementName=cmbBox,Path=SelectedValue}" ContentTemplate="{StaticResource robinTemplate}"/>
For making the Selected content display in the same way :
Create a copy of the combobox control template and you will find a ContentPresenter there. Replace that with the ContentControl.. This is not the right solution though.

Categories