Windows Phone 8 TextBlock - c#

How do I hide a TextBlock in Windows Phone 8 if it has no text?
<StackPanel>
<TextBlock Text="{Binding Name}" FontSize="22" Margin="0,5,10,0" TextWrapping="NoWrap" TextAlignment="Center" TextTrimming="WordEllipsis" />
<Image Source="{Binding Icon}" MaxWidth="36" MaxHeight="36" HorizontalAlignment="Left" Margin="10,-33,10,10" Stretch="Fill"/>
<TextBlock Text="{Binding Description}" FontSize="14" Margin="10,0,10,5" MaxHeight="60" TextWrapping="Wrap" TextTrimming="WordEllipsis" />
</StackPanel>
I would like to hide the textblock "description" if it doesn't have any text inside it. How would this be possible?
It's a multiple "viewmodel" textblock, therefore it has no name and can't be checked individually, due to performance issues of loading over 20+ every 5 - 15 seconds.

You will need to create an IValueConverter that analyses the length of the string,
public class HideEmptyStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var input = (string)value;
return string.IsNullOrWhiteSpace(input) ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
add an instance of the converter to your page's resources and then bind the Visibility property to the description using that converter...
<TextBlock Text="{Binding Description}" Visibility="{Binding Description, Converter={StaticResource HideEmptyStringConverter}}" FontSize="14" Margin="10,0,10,5" MaxHeight="60" TextWrapping="Wrap" TextTrimming="WordEllipsis" />

Related

c# wpf in a listbox doing binding with checkbox to an object within another object

I have a Listbox which consists of elements that looks like this.
class ItemForListbox
{
public string path { get; set; }
public string file { get; set; }
public InstallationPackageChoice choices { get; set; }
public KeepKill keepKill { get; set; }
}
The choices and keepKill are objects.
My XAML for the listbox has this DataTemplate
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Name="btnPackageVersion" Style="{StaticResource ListBoxButtonFormat}" Content ="Package version" Click="btnInstallPackage_Click" HorizontalAlignment="Right"/>
<TextBlock Name="txtBlkPath" Text="{Binding path}" FontSize="10" Width="500" Height="20" Margin="10,10,0,0"/>
<Button Name="btnFilterPath" Style="{StaticResource ListBoxButtonFormat}" Content ="Filter path" Click="btnFilterpath_Click" HorizontalAlignment="Right"/>
<TextBlock Name="txtBlkFile" Text="{Binding file}" FontSize="10" Width="150" Height="20" Margin="10,10,0,0"/>
<Button Name="btnFilterfile" Style="{StaticResource ListBoxButtonFormat}" Content="Filter file" Click="btnFilterfile_Click" HorizontalAlignment="Right"/>
<CheckBox Name="chkBxKeep" Content="Keep" VerticalAlignment="Center" HorizontalAlignment="Right" IsChecked="True" Checked="chkBxKeep_Checked"/>
<CheckBox Name="chkBxKill" Content="Kill" VerticalAlignment="Center" HorizontalAlignment="Right" Checked="chkBxKill_Checked"/>
<Separator Name="MySeparator"
Height="3"
Width="Auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Background="Red" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
The two checkboxes underlying data is the killKeep object in the Listbox element object.
The problem is that i would like to have a radiobutton functionality of the two checkboxes, so when i check a checkbox, the other one unchecks. The reason i dont use radiobuttons are that i simply do not understand them in regards to binding. But now i find i also do not know how to do this binding with the checkboxes.
I hope someone can help me.
You can use binding with a converter to bind IsChecked property of checkboxes:
<Window.Resources>
<local:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
</Window.Resources>
...
<CheckBox Name="chkBxKeep" Content="Keep" VerticalAlignment="Center" HorizontalAlignment="Right" IsChecked="True" Checked="chkBxKeep_Checked"/>
<CheckBox Name="chkBxKill" Content="Kill" VerticalAlignment="Center" HorizontalAlignment="Right" Checked="chkBxKill_Checked"
IsChecked="{Binding ElementName=chkBxKeep, Path=IsChecked, Converter={StaticResource InverseBooleanConverter}}"/>
Converter
public class InverseBooleanConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && value is bool)
{
return !(bool)value;
}
return true;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Convert(value, targetType, parameter, culture);
}
#endregion
}

Able to add Text to a textblock after binding?

so i've a Textblock that binds a property using the (Text="x"), but is there a way to add more text to it?
So this is the line in XAML
<TextBlock Name="UpdatedStock" FontSize="12" Text="{x:Bind Stock, Mode=TwoWay}" HorizontalAlignment="Left" />
and it only says the number of Stock atm, but i want it to say "X in stock". But i cant add more text to it, is there a way somehow to add it on the same line or i have to do it somewhere else?
Kinds regards
Able to add Text to a textblock after binding?
You have many ways to approach. In general we often add new TextBlock with static text X and place left of UpdatedStock
<RelativePanel>
<TextBlock
x:Name="UpdatedStock"
FontSize="12"
RelativePanel.AlignLeftWithPanel="True"
Text="{x:Bind Stock, Mode=OneWay}" />
<TextBlock Margin="2,0,0,0"
FontSize="12"
RelativePanel.RightOf="UpdatedStock"
Text="X" />
</RelativePanel>
And the other way is use IValueConverter to append X to Stock propety.
public class StringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value == null)
return null;
return value.ToString()+ "X";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Usage
<Page.Resources>
<local:StringConverter x:Key="StrConverter" />
</Page.Resources>
<Grid>
<TextBlock
x:Name="UpdatedStock"
FontSize="12"
RelativePanel.AlignLeftWithPanel="True"
Text="{x:Bind Stock, Mode=OneWay, Converter={StaticResource StrConverter}}" />
</Grid>

Xaml ResourceKey as a variable not working

I'm using a ComboBox (WPF 4.0) to show user defined paragraph styles for an editor app. The ComboBox has two columns:
(1) Name of the paragraph style
(2) Text "abcABC123", should in some properties be formatted according to the paragraph style in the first column
(1) is working, (2) is not because _ResourceKey_background, _ResourceKey_foreground and _ResourceKey_fontFamily are no ResourceKeys
but variables containing ResourceKeys. How can I solve this?
_NameInternal, _NameUI, _ResourceKey_background, _ResourceKey_foreground and _ResourceKey_fontFamily are public properties
of the user defined paragraph style class.
<ComboBox Name="_cbStylesPara" SelectedValuePath="_NameInternal"
ItemsSource="{Binding Source={StaticResource _collectionViewSource_stylesPara}}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="{Binding _NameUI}" VerticalAlignment="Center" />
<TextBlock Grid.Column="1" Text="abcABC123" Margin="3,0,0,0" VerticalAlignment="Center"
Background="{DynamicResource _ResourceKey_background}"
Foreground="{DynamicResource _ResourceKey_foreground}"
FontFamily="{DynamicResource _ResourceKey_fontFamily}" />
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
As like you said resources are declared under App resources, what you can do is create an IValueConverter and return the resource value from it's Convert method.
public class ResouceLookupConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return App.Current.TryFindResource(value);
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return Binding.DoNothing;
}
}
XAML:
<ComboBox>
<ComboBox.Resources>
<local:ResouceLookupConverter x:Key="ResouceLookupConverter"/>
</ComboBox.Resources>
......
<TextBlock Grid.Column="1" Text="abcABC123" Margin="3,0,0,0"
VerticalAlignment="Center"
Background="{Binding _ResourceKey_background,
Converter={StaticResource ResouceLookupConverter}}"
Foreground="{Binding _ResourceKey_foreground,
Converter={StaticResource ResouceLookupConverter}}"
FontFamily="{Binding _ResourceKey_fontFamily,
Converter={StaticResource ResouceLookupConverter}}" />
</ComboBox>
Note: Ofcourse you have to define local namespace in your XAML set to the namespace where your Converter is declared.

How to implement a converter in WP8 using XAML and C# for capitalize the first letter of a word in a TexBlock?

I have a data template with a TexBlock in XAML. This TexBlock shows a word in a word list. Every word I want to put the first letter capitalized, because all words are in lowercase.
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="AddrBookItemTemplate">
<StackPanel VerticalAlignment="Top">
<TextBlock Margin="5,0,0,0" FontSize="20" Text="{Binding name}" />
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
In c# implement the converter
namespace Converter.ViewModels
{
public class ToCapitalizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return char.ToUpper(value.ToString()[0]) + value.ToString().Substring(1);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (value as string).ToLower();
}
}
}
In App.xaml
...
xmlns:vm="clr-namespace:Converter.ViewModels"
<Application.Resources>
<vm:ToCapitalizeConverter x:Key="ToCapitalizeConverter"/>
</Application>
In MainPage.xaml
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="AddrBookItemTemplate">
<StackPanel VerticalAlignment="Top">
<TextBlock Margin="5,0,0,0" FontSize="20" Text="{Binding name, Converter={StaticResource ToCapitalizeConverter}}" />
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
You can use a converter as follows:
<TextBlock Margin="5,0,0,0" FontSize="20" Text="{Binding name, Converter ={StaticResource myConverter}}" />
Specific information on how to implement a converter can be found here. You can essentially perform any operation you like on the text. I actually like Humanizer to do these type of text conversions.

Automatic data update in WPF

<Window x:Class="Binding2.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">
<StackPanel Orientation="Vertical">
<StackPanel HorizontalAlignment="Left" Name="stackPanel1" VerticalAlignment="Top" Width="165" Orientation="Horizontal">
<TextBlock Height="20" Name="_sourceTextBlock" Text="Source" Width="67" />
<TextBox Height="20" Name="_sourceTextBox" Width="92" />
</StackPanel>
<StackPanel HorizontalAlignment="Left" Name="stackPanel2" VerticalAlignment="Top" Width="165" Orientation="Horizontal">
<TextBlock Height="20" Name="_destTextBlock" Text="Destination" Width="67" />
<TextBox Height="20" Name="_destTextBox" Width="92" />
</StackPanel>
</StackPanel>
</Window>
I have two text boxes. How can I program that the value in Destination text box is automatically modified based on the value in Source text box? For example, when the value in Source is "abc", how can I make the value in Destination is automaticaly "x" + "abc" + "x"? Or, make destination the number 10*source.
ADDED
I also found a way to get the result when the source is more than one - Bind an element to two sources
That's easy using MVVM :
public class MainWindowViewModel : ViewModelBase
{
private string _source;
public string Source
{
get { return _source; }
set
{
_source = value;
OnPropertyChanged("Source");
OnPropertyChanged("Destination");
}
}
public string Destination
{
get { return "x" + _source + "x"; }
}
}
Use that class as the DataContext for your view, and bind one TextBox to Source (TwoWay), and the other to Destination (OneWay):
<StackPanel Orientation="Vertical">
<StackPanel HorizontalAlignment="Left" Name="stackPanel1" VerticalAlignment="Top" Width="165" Orientation="Horizontal">
<TextBlock Height="20" Name="_sourceTextBlock" Text="Source" Width="67" />
<TextBox Height="20" Name="_sourceTextBox" Width="92" Text="{Binding Source, Mode=TwoWay}" />
</StackPanel>
<StackPanel HorizontalAlignment="Left" Name="stackPanel2" VerticalAlignment="Top" Width="165" Orientation="Horizontal">
<TextBlock Height="20" Name="_destTextBlock" Text="Destination" Width="67" />
<TextBox Height="20" Name="_destTextBox" Width="92" Text="{Binding Destination, Mode=OneWay}" IsReadOnly="True" />
</StackPanel>
</StackPanel>
Anyway, if you're building a non-trivial WPF application, I strongly recommend moving to the MVVM pattern, in the long-term your app will be much easier to maintain.
There are a couple of approaches you could use, the first is purely within the UI by using Elementname binding:
<TextBox Height="20" Name="_destTextBox"
Text="{Binding Path=Text, ElementName=_sourceTextBox}"/>
This will synchronize the TextBoxes, add a ValueConverter if you want to add text before and after. For example:
public class MyValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return "x" + (string)value + "x";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
And used as follows:
<Window x:Class="Binding2.MainWindow"
....
xmlns:local="clr-namespace:Binding2"
....
<Window.Resources>
<MyValueConverter x:Key="MyValueConverter"/>
</Window.Resources>
...
<TextBox Height="20" Name="_destTextBox"
Text="{Binding Path=Text, ElementName=_sourceTextBox, Converter={StaticResource MyValueConverter}}"/>
The other approach would be to create a ViewModel layer than binds to your view and performs this logic.
quickest way would be to use ValueConverter or have 2 separate properties in your ViewModel so that one is bound to Source Property in VM, and other derives from the Source (i.e. decorates it with "X" and returns it)
Example(you should implement INotifyPropertyChanged so that Binding engine picks up the Destination change and refreshed the textbox in your GUI):
public string Source { get; set; }
public string Destination {get{
return "X" + Source + "X"
}
}
You can use StringFormat, i.e.: StringFormat='x{0}x', e.g.:
<TextBox Height="20" Name="_destTextBox" Width="92"
Text="{Binding ElementName=_sourceTextBox, Path=Text, StringFormat='x{0}x'}" />

Categories

Resources