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
Related
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 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();
I have an ObservableCollection<MyEntity> and MyEntity has a IsChecked property with a PropertyChanged event.
I have a Button and I would like to change IsEnabled property to true when at least one of MyEntity of the MyObservableCollection is checked.
I created a converter which takes the ObservableCollection and return true when a MyEntity is checked at least.
But the return "null" is returned.
What is wrong ? Thank you for your help.
XAML
<Window.Resources>
<CollectionViewSource x:Key="MyObservableCollection"/>
<src:MyConverter x:Key="MyConverter"/>
</Window.Resources>
<Button IsEnabled="{Binding Converter={StaticResource MyConverter}, Source={StaticResource MyObservableCollection}}"/>
C# Converter
class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (null == value)
return "null";
ReadOnlyObservableCollection<object> items = (ReadOnlyObservableCollection<object>)value;
List<MyEntity> myEntities = (from i in items select (MyEntity)i).ToList();
foreach (MyEntity entity in myEntities)
{
if (entity.IsChecked)
{
return true;
}
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
I think your Binding is wrong. The Converter want's the underlying collection not the CollectionView. And set the CollectionViewSource.Source after InitializeComponent(), the Binding will be refreshed.
<Button IsEnabled="{Binding Path=SourceCollection,
Converter={StaticResource MyConverter},
Source={StaticResource MyObservableCollection}}" />
Since StaticResources are resolved at the time of intializing itself i.e. at the time of InitializeComponent() but till that time your collection is yet not intialized that's why null value is passed to the converter.
So, better choice would be to move that property in your code behind and bind to that property since binding will be resloved after InitializeComponent(). Create property in your code-behind-
public CollectionViewSource MyObservableCollection { get; set; }
and bind to your button -
<Button IsEnabled="{Binding MyObservableCollection, RelativeSource=
{RelativeSource AncestorType=Window}, Converter={StaticResource MyConverter}}"/>
I'm trying to make a custom converter that inherits from DependencyObject, but it doesn't work:
Converter:
public class BindingConverter : DependencyObject , IValueConverter
{
public object Value
{
get { return (object)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(object), typeof(BindingConverter), new PropertyMetadata(null));
public object Convert(object value, Type targetType, object parameter, Globalization.CultureInfo culture)
{
Debug.Assert(Value != null); //fails
return Value;
}
public object ConvertBack(object value, Type targetType, object parameter, Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Xaml:
<StackPanel x:Name="this">
<!--works-->
<ContentControl Content="{Binding ActualHeight, ElementName=this}"/>
<!--doesn't work-->
<ContentControl>
<Binding>
<Binding.Converter>
<BindingConverter Value="{Binding ActualHeight, ElementName=this}" />
</Binding.Converter>
</Binding>
</ContentControl>
<TextBlock Text="{Binding Animals}"/>
</StackPanel>
Am I missing out anything?
I have some places in my projects where I needed similar functionality. Can't show you exact sample, just an idea:
perhaps you have to inherit from FrameworkElement, not IValueConverter, Something like this:
public class BindingHelper : FrameworkElement
in the BindingHelper class, set Visibility to Collapsed and IsHitTestVisible to false;
to make it working, insert it into visual tree directly. In your example, it should be a child of the StackPanel. So, it will have the same DataContext as other StackPanel children;
then, you can add one ore more dependency properties depending on your needs. For example, you might have single property for the source of data and some different properties which you then will use as converter return values. Handle all changes to the source property in your BindingHelper class and change output properties accordingly;
bind other controls to properties of the BindingHelper class using ElementName syntax
in Silverlight, ActualHeight and ActualWidth properties don't do notifications on property updates. So, binding to them won't work.
Note! ActualHeight property's binding is buggy on binding!
Why you inherit DependencyObject when coding a converter? You should just implement IValueConverter.
Try that,
First add MyConverter by the key of "MyConverterResource" on your resources then,
You can do than on XAML side or on cs side by
//You may do it on XAML side <UserControl.Resources>...
this.Resources.Add("MyConverterResource",new MyConverter());
<TextBlock Text="{Binding ActualHeight,ElementName=this
,Converter=MyConverterResource}"/>
public class MyConverter: IValueConverter
{
public object Convert(object value, Type targetType
, object parameter,Globalization.CultureInfo culture)
{
return "Your Height is:"+Value.toString();
}
}
Hope helps
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.