I would like to change the content of a control based on its current CheckState (checked, unchecked, indeterminate). If possible I would like the solution to use only XAML and require no code behind.
I am wondering which control to use and how to define the multiple sets of content.
Example: A "ToggleContent" control that displays UserControl1 when the checked state is Unchecked and UserControl2 when the checked state is Checked.
The XAML might look something like this:
<ToggleContent>
<ToggleContent.ContentUnchecked>
<local:UserControl1></local:UserControl1>
</ToggleContent.ContentUnchecked>
<ToggleContent.ContentChecked>
<local:UserControl2></local:UserControl2>
</ToggleContent.ContentChecked>
</ToggleContent>
I'm not sure what "no code behind" means, but this sounds like a perfect example for using a ValueConverter and changing visibility based on the check state.
It would look something like this:
<StackPanel>
<CheckBox x:Name="MyCheckBox"/>
<local:UserControl1 Visibility="{Binding IsChecked, ElementName=MyCheckBox, Converter={StaticResource BoolToVis}, ConverterParameter=False">
<local:UserControl2 Visibility="{Binding IsChecked, ElementName=MyCheckBox, Converter={StaticResource BoolToVis}, ConverterParameter=True">
The Converter:
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) return Visibility.Collapsed;
bool comparer = true;
if(parameter != null)
{
comparer = System.Convert.ToBoolean(parameter);
}
return System.Convert.ToBoolean(value) == comparer ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Here's a nice post from Jeff Wilcox on value converters
You can create a style to CheckBox or ToggleButton, replace the ContentPresenter inside the style by your UserControls and change them visibility in the CheckStates.
id create a user control based on the checkbox and use the visualstatemanager to load your controls.
Related
I saw many posts on how to bind a boolean value to a radio button. But my scenario is that I need to bind it to a radio button and read the selection from the user.
That is no option should be selected intially.
If I bind it to a boolean, since boolean cant be null it shows the default value selected in radio button.
If I use nullable boolean, I still defaults to false when trying to use the converter.
I cant use oneway mode in xaml as I need to check if the radio button selection was made which I do using the bounded variable.
Ant pointers on how to achieve this?
You can bind a nullable boolean to your radio buttons, but you need to do it through a converter.
First declare your variable:
private bool? answer;
public bool? Answer
{
get { return answer; }
set
{
answer = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Answer"));
}
}
and initialise it to null.
Then in the XAML:
<Window.Resources>
<local:BooleanConverter x:Key="BooleanConverter"/>
</Window.Resources>
<StackPanel Grid.Row="1">
<RadioButton Content="I Agree"
IsChecked="{Binding Answer,
Converter={StaticResource BooleanConverter},
ConverterParameter='true', Mode=TwoWay}" />
<RadioButton Content="I Disagree"
IsChecked="{Binding Answer,
Converter={StaticResource BooleanConverter},
ConverterParameter='false', Mode=TwoWay}" />
</StackPanel>
And finally your converter:
class BooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var test = (bool?)value;
var result = bool.Parse((string)parameter);
if (test == result)
{
return true;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var result = bool.Parse((string)parameter);
return result;
}
}
This binds the radio button to Answer and states that the first one will only be checked when the value is true and the second one will be checked when the answer is false. You can then check that Answer is not null before letting the user proceed.
This may not be the best way of doing it, but you could use something similar to this:
checkbox like radiobutton wpf c#
and just have two controls.
I appreciate it's not the best, but reading your answer it gives you what you want (generally).
I have a bound WPF comboBox that has an ItemsSource set to a CompositeCollection. I'm trying this to try and accomodate adding <Select> and <Add New...> selections to precede an ObservableCollection of 'regular' objects. What I can't figure out is how to, in code-behind, select one of these added choices.
This is how I'm building the CompositeCollection:
private CompositeCollection CreateItemsSource(ObservableCollection<T> source)
{
CompositeCollection cmpc = new CompositeCollection();
cmpc.Add(new ComboBoxItem { Content = "<Select>" });
cmpc.Add(new ComboBoxItem { Content = "<Add New...>" });
var cc1 = new CollectionContainer { Collection = source };
cmpc.Add(cc1);
return cmpc;
}
This is what the ComboBox looks like:
<DataTemplate x:Key="LookupComboTemplate">
<TextBlock Text="{Binding}"/>
</DataTemplate>
<ComboBox ItemsSource="{Binding SubCategories.ItemsSource}"
ItemTemplate="{StaticResource LookupComboTemplate}">
<ComboBox.SelectedItem>
<Binding Path="SourceData.SubCategoryObj" Mode="TwoWay"></Binding>
</ComboBox.SelectedItem>
</ComboBox>
I've got a situation where SelectedItem SourceData.SubCategoryObj is null (it's an optional property). In this case, I want to manually select and display the <Select> choice. But no matter what I do (setting SelectedIndex is ignored, setting SelectedValue to the ComboBoxItem in the CompositeCollection is ignored) I get a blank ComboBox when it renders.
I'd appreciate any advice on how I can do this.
Thanks!
Corey.
You should be able to fix this with a custom valueconverter for your SelectedItem binding. http://wpftutorial.net/ValueConverters.html should give you some pointers.
I'm not sure if combox wants a simple string or some composite object but you can check that. Something like
public class ComboConverter: IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return "<Select>";
return value;
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
if (value.toString().Equals("<Select>")
return null;
return value;
}
should give you the "<Select>" entry if the selected item is null.
I am working in Silverlight4 VS 2010.I have placed a CheckBox in my .xaml file. I need it's DataContextChanged event. But unfortunately i didn't find it.
Here is my CheckBox :
<CheckBox x:Name="chkRegion" Content="{Binding name}" Click="CheckBox_Click" ></CheckBox>
Could you please help me in to find DataContextChanged in SL 4 VS 2010.
Thanks, Rajbir
Implement an Converter (its just a simple class which gets derived from IValueConverter and implement the interface methods)
public class ChangeIsCheckedValConverter : IValueConverter
{
public object Convert(object value,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
if (value != null)
{
//value here is the object which you are binding to the DataContext of
Checkbox ; //return the bool (true or false) based on your valued
binded to your checkbox
}
public object ConvertBack(object value,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
return null;
}
You will have to add the name space of you newly implemnted converter whereever you will want to use .
Then use this converter where your checkbox is defined in datatemplate as below :
//First define the key as below :
<converters:VisibilityConverter x:Key="changeConverter" />
<CheckBox x:Name="chkRegion" Content="{Binding name}" IsChecked={Binding ,Converter={StaticResource changeConverter}}"} Click="CheckBox_Click" ></CheckBox>
I have a portion of a Window that should display one of several UserControls. Each UserControl presents the same data, only in a different format, arrangement, and style. The particular UserControl that will be presented in this section of the Window should be determined by a single setting that is stored in the ViewModel of the Window.
How can I make it so that the program end user can change the UserControl that is displayed in the Window at run-time?
I figured it out. In my ViewModel, I have a UserControl property called SelectedUC, and another property, called Style, that is an enum type, which enumerates the different UserControls that I am using. In the set part of the Style property I have OnPropertyChanged("SelectedUC"); The get part of the SelectedUC property has a switch-case statement that sets the field of the SelectedUC to a new instance of the corresponding type of UserControl and passes the ViewModel (this) as a parameter.
private MyStyleEnum _style = MyStyleEnum.OneStyle;
public MyStyleEnum Style
{
get { return _style; }
set
{
if (value != _style)
{
_style = value;
OnPropertyChanged("Style");
OnPropertyChanged("SelectedUC");
}
}
}
private UserControl _selectedUC;
public UserControl SelectedUC
{
get
{
switch (Style)
{
case MyStyleEnum.OneStyle:
_selectedUC = new ucOneControl(this);
break;
case MyStyleEnum.AnotherStyle:
_selectedUC = new ucAnotherControl(this);
break;
}
return _selectedUC;
}
set { _selectedUC = value; }
}
In my MainView's xaml, I have a ContentPresenter with the Content property bound to the SelectedUC property in the ViewModel.
<ContentPresenter Content="{Binding SelectedUC}" />
In my SettingsView's xaml, I have a group of RadioButtons that are all bound to the Style property and use a Converter and ConverterParameter.
<Window x:Class="MyProject.View.SettingsView"
xmlns:cv="clr-namespace:MyProject.Converters"
xmlns:vm="clr-namespace:MyProject.ViewModel">
<Window.Resources>
<cv:EnumToBoolConverter x:Key="EBConverter"/>
</Window.Resources>
<RadioButton Content="One" IsChecked="{Binding Path=Style, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ResourceKey=EBConverter}, ConverterParameter={x:Static Member=vm:MyStyleEnum.SingleLine}}"/>
</Window>
EnumToBoolConverter.cs:
public class EnumToBoolConverter : IValueConverter
{
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;
}
}
One (quick but not necessarily best) way is to add a ContentControl to your window
<ContentControl Name="cc" />
Then set the content of it however you like. Eg. set it in code-behind
cc.Content = new UserControl1();
hi
i am new to silverlight 4.
i have two radio buttons in my views by name Internal and External in a stackpanel1,which are binded to my view model.
in stackpanel2 i have textblock and button.
now what i need when i select internal radio button stackpanel2 should be visible and on external selection stackpanel2 should be invisible.
so how i bind stackpanel2 visibility property to my viewmodel.
pls solve ma problem as soon as possible.
# anju no-problem, you have to add a new class inherit it with IValueConverter this will be your bool to visibility converter, Now u have to Bind StackPanel Visibility property with boolean property from your view model like this:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:GreenScreenApp.classes" x:Class="GreenScreenApp.one" >
<UserControl.Resources>
<local:VisibilityConverter x:Key="BoolToVisibilityConverter"/>
</UserControl.Resources>
<Grid DataContext="MyDataSource" x:Name="LayoutRoot" >
<StackPanel x:Name="stackpanel2" Visibility="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}">
</StackPanel>
</Grid>
you should have a property named "IsVisible" in data context. Converter will convert boolean and return visibility values.
Converter Code
public class VisibilityConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var v = value;
if (v == "true")
return "Visible";
else
return "Collapsed";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
just want to let you know in my case converter class is in folder "classes" at root of project.
Hope it will solve your problem.
You have to add new Visibility property in your data model and then bind this property to stackpanel Visibility property, further you can bind it with a boolean property too but then you have a need of converter. Converters in silverlight convert any assigned value to a value of property type.
You can learn how to build converter here.
http://weblogs.asp.net/dwahlin/archive/2009/08/15/so-what-s-a-silverlight-value-converter-anyway.aspx