Binding items in ListBox in WP8 - c#

In a Windows Phone 8 app,
I have a listbox with 2 TextBlocks and a button.
I have a list of 2 strings and a boolean & I am able to bind the strings to the TextBlocks.
<ListBox Name="ListboxTest">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Value}" TextWrapping="Wrap"/>
<Button />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And this is the C# code to bind to the list box.
public class Detail
{
public string Key { get; set; }
public string Value { get; set; }
public bool check { get; set; }
}
public List<Detail> ClassList = new List<Detail>();
ListboxTest.ItemsSource = ClassList;
I want to display the button only when the boolean value is true.
How do I do it?

Take a look at this. Actually what you really need is a Converter by implementing the IValueConverter. This is also a good example where you could read about it. Bind the boolean value with the visibility property of the button and you are done! ;)

You can use boolean to visibility converter to hide, show button
Here are example:
public class BoolToVisibility : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var boolValue = false;
if (value != null) boolValue = (bool)value;
return boolValue ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
In app.xaml
<my:BoolToVisibility x:Key="BoolToVisibility"/>
In your data template
<Button Visibility="{Binding Path=YourBoolProperty,Converter={StaticResource BoolToVisibility}}>

Or, you could add this property to the Detail class:
public Visibility ButtonVisibility {
get {
return this.check == true ? Visibility.Visible : Visibility.Collapsed;
}
}
And then just bind the button's Visibility to the ButtonVisibility property without any converters.
<Button Visibility="{Binding ButtonVisibility}" />

Please try those use Triggers.
Various Triggers in windows phone Msdn.
Please use ObservableCollection in WP8 for binding instead of List.
Please make your properties are implemented with INotifyPropertyChanged If your Boolean property is not implemented with inotifypropertychanged the view will not know the value is changed.hence the Data trigger will not work.
Namespace
xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ec="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
x:Class="XXX_XXXX"
<Button Content="My button"
Stretch="None"
HorizontalAlignment="Stretch"
VerticalAlignment="Top">
<interactivity:Interaction.Triggers>
<ec:DataTrigger Binding="{Binding Check}" Value="True">
<ec:ChangePropertyAction PropertyName="Visibility">
<ec:ChangePropertyAction.Value>
<Visibility>Visible</Visibility>
</ec:ChangePropertyAction.Value>
</ec:ChangePropertyAction>
</ec:DataTrigger>
<ec:DataTrigger Binding="{Binding Check}" Value="False">
<ec:ChangePropertyAction PropertyName="Visibility">
<ec:ChangePropertyAction.Value>
<Visibility>Collapsed</Visibility>
</ec:ChangePropertyAction.Value>
</ec:ChangePropertyAction>
</ec:DataTrigger>
</interactivity:Interaction.Triggers>
</Button>
Note Answered from phone syntax may not be correct

Related

Condition in XAML to change component

I've a combobox, which allows me to select a type. When I select a type, i'm able to fill a component. But I'd like that my component corresponding to my type. So, if it's a date, i'd like to display a datepicker, and if it's a string, i'd like to display a textbox.
How can I do that ?
I don't want to change things around DataTemplate, because this row is a part of a datagrid :)
<DataGridTemplateColumn Header="SQLValue" Width="0.55*" CanUserResize="False" CanUserReorder="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!-- HERE ! HOW CAN I CHOOSE ONE BY A CONDITION ? -->
<DatePicker/>
<TextBox Text="{Binding SqlValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
The idea here is: you should a property in data context call DispType (int)
Then in each control you binding Visibility with above property, include a Converter convert number to Visible or not, Converter have parameter is number.
You can see my eg:
<Grid>
<Button Visibility="{Binding DispType, Converter={StaticResource VisibilityTypeConverter}, ConverterParameter=1}"/>
<TextBox Visibility="{Binding DispType, Converter={StaticResource VisibilityTypeConverter}, ConverterParameter=2}"/>
<DatePickerTextBox Visibility="{Binding DispType, Converter={StaticResource VisibilityTypeConverter}, ConverterParameter=3}"/>
</Grid>
You see the hard code for ConverterParameter.
And Converter class
public class VisibilityTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int actualType = parameter == null ? 0 : System.Convert.ToInt32(parameter);
int compareType = value == null ? 0 : System.Convert.ToInt32(value);
if (actualType == compareType)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Please not that code is only demo, you should change code to meet your expectation.

UWP Show a check symbol when boolean is true

I have a ListView with all kind of tasks that have to be completed. When a task is completed a user presses on the item in the listview. This changes a boolean in my web api. Now I want to display a check symbol on the items that are already completed when I get all the items from my API.
<SymbolIcon Grid.Column="0" x:Name="CompleteTask" Symbol="Accept"/>
<TextBlock Name="TaakNaam"
Grid.Column="1"
Text="{x:Bind TaskName}"
FontSize="16"/>
What it should be
you can write property
public Visibility TickVisibility
{
get {return YourBoolean == true ? Visibility.Visible : Visibility.Collapsed;}
}
and Bind it:
<SymbolIcon Grid.Column="0" x:Name="CompleteTask" Symbol="Accept" Visibility={Binding TickVisibility}/>
or use NotifyProperty every time YourBoolean has changed
or write Converter that will implement IValueConverter and will convert bool<=>Visibility
I created this Converter:
public class BooleanToVisibilityConverter : IValueConverter
{
public BooleanToVisibilityConverter()
{
}
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is bool && (bool) value)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return (value is Visibility && (Visibility)value == Visibility.Visible);
}
}
And imported this in my view:
<Page.Resources>
<vm:BooleanToVisibilityConverter x:Key="BoolToVis" />
</Page.Resources>
Than I added a binding to my SymbolIcon:
<SymbolIcon Grid.Column="0" x:Name="CompleteTask" Symbol="Accept" Foreground="Green" Visibility="{Binding Path=Check, Converter=StaticResource BoolToVis}}"/>
Source: https://pmdevweb.wordpress.com/2016/05/24/uwp-binding-boolean-to-visibility/

Expressions in Databinding... possible? How to?

I have a collection databound to a ListBox. What I would like to do is show some UI based on whether or not some property of the member of the collection exists.
E.g.:
public class Widget
{
public string foo;
public string bar;
}
public ObservableCollection<Widget> Stuff;
XAML:
<ListBox ItemsSource="{Binding Stuff}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding foo}"
Visiblity="{Binding
(foo != null ? Visibility.Visible : Visibility.Collapsed)
}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Note the Visibility attribute on the TextBlock. Clearly this isn't supported, but it should give you an idea of what I want to do.
One possible solution is that I could add a property to widget that looks like this:
public Visibility has_foo;
And then:
... Visibility="{Binding has_foo}" ...
But it seems awkward to have to generate these additional properties.
I suspect there is a much better way. Is there? How would you do it?
Thanks.
Create a value converter. Something like
public class NullToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value != null ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then add it something like
<YourUserControl.Resources>
<NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
</YourUserControl.Resources>
<ListBox ItemsSource="{Binding Stuff}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding foo}"
Visiblity="{Binding foo,
Converter={StaticResource NullToVisibilityConverter}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Obviously I've not implemented ConvertBack (not really sure if you will be able to convert back) but you shouldn't need it in this instance.

Silverlight: Difficulty with binding to visiblity

I have two elements: a listbox and a "this list is empty" message. I'd like to bind their visibility to the list box's ItemsSource being empty. However, I'm not sure how to do this:
<TextBlock Text="No favorite searches yet. Add some by searching, then clicking 'Add to Favorites'"
Padding="10,0"
VerticalAlignment="Center"
Visibility="{Binding Path=FavoriteFilters.IsEmpty, Converter={StaticResource visibilityConverter}}"
/>
<ListBox ItemsSource="FavoriteFilters"
x:Name="favoriteFiltersList"
Visibility="{Binding Path=FavoriteFilters.IsEmpty, Converter={StaticResource visibilityConverter}}">
<ListBox.ItemTemplate>
<DataTemplate>
<my:FavoriteFilterLink />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
They are both visible, although the ItemsSource is empty. Also, I'm not sure how to invert the condition for the ListBox.
The visibility converter:
public class VisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool?)
{
if (string.IsNullOrEmpty((string)parameter))
{
return (value as bool?).Value ? Visibility.Visible : Visibility.Collapsed;
} else
{
return (value as bool?).Value ? Visibility.Collapsed : Visibility.Visible;
}
}
throw new ArgumentException();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
You might be better off writing two converters, one for the ListBox the other for the TextBlock. The logic of each would be simpler and you wouldn't need to pass a parameter to get the correct result.
While it might not be as elegant as a single converter solution it will be far more maintainable.
If you really want to pass a parameter then you need to use the ConverterParameter.
There's an example here but I'm not 100% sure it'll meet your requirements. The simplified XAML syntax is:
<TextBlock Visibility="{Binding FavoriteFilters.IsEmpty,
Converter={StaticResource visibilityConverter}, ConverterParameter=false}"/>
<ListBox Visibility="{Binding FavoriteFilters.IsEmpty,
Converter={StaticResource visibilityConverter}, ConverterParameter=true}"/>
Then in your converter (simplified):
bool show = (bool)value;
bool visible = (bool)parameter;
if (visible)
{
return show ? Visibility.Visible : Visibility.Collapsed;
}
else
{
return show ? Visibility.Collapsed : Visibility.Visible;
}

How to get the selected index of MVVM-bound radiobuttons?

I have an ItemsControl which is bound and set to an observablecollection in my viewmodel:
<ItemsControl ItemsSource="{Binding AwaySelection}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding AwayText}" ></RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Now, how to find out which one is clicked? I would like to bind the IsChecked value of each Radiobutton to a single variable in the viewmodel that returns an index to the collection. This would make it very easy for me to directly reference the selected item. Any ideas?
This is how I solved this problem. I wrote an EnumToBool converter for this, like
public class EnumToBoolConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value,
Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (parameter.Equals(value))
return true;
else
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return parameter;
}
#endregion
}
And I've the following enumeration
public enum CompanyTypes
{
Type1Comp,
Type2Comp,
Type3Comp
}
Now, in my Xaml, I'm passing the types as the converter parameter.
<Window x:Class="WpfTestRadioButtons.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTestRadioButtons"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<local:EnumToBoolConverter x:Key="EBConverter"/>
</Window.Resources>
<Grid>
<StackPanel>
<RadioButton IsChecked="{Binding Path=Type,
Converter={StaticResource EBConverter},
ConverterParameter={x:Static local:CompanyTypes.Type1Comp}}" Content="Type1"/>
<RadioButton IsChecked="{Binding Path=Type,
Converter={StaticResource EBConverter},
ConverterParameter={x:Static local:CompanyTypes.Type2Comp}}" Content="Type2"/>
</StackPanel>
</Grid>
</Window>
Now, in your view model, you should have a property (in this case Type), which is of that Enum type.
Like,
public CompanyTypes Type
{
get
{
return _type;
}
set
{
_type = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Type"));
}
}
In this example, you might have noticed that Radiobuttons are static. In your case, as you are listing the radio buttons inside an Item control, you need to bind your ConverterParameter of your RadioButton as well, to the correct type.
In the end, I put the radio buttons into a listview, and bind the isselected property of the listview to the radiobutton one.
link Forum post describing this technique
When use MVVM with radiobutton control exits a problem on method onToggle(), but you can create a radiobutton for that.
public class DataBounRadioButton: RadioButton
{
protected override void OnChecked(System.Windows.RoutedEventArgs e) {
}
protected override void OnToggle()
{
this.IsChecked = true;
}
}
Then add reference to control and Binding a property, in my case IsActive.
<controls:DataBounRadioButton
IsChecked="{Binding IsActive}"/>

Categories

Resources