i have a custom userControl with DPs and have the problem that the binding to these properties only works if i use the controls outside of datatemplates.
Outside of Datatemplates works the usercontrol great.
XAML to Test the UserControl in a DataTemplate
<GroupBox Header="DataTemplate" Padding="5">
<ItemsControl ItemsSource="{Binding Dummies}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="local:Dummy">
<StackPanel Orientation="Horizontal" Margin="2">
<common:QuarterPicker SelectedFirstDay="{Binding Gueltigkeit}" Margin="5,0" />
<!--control the value of the item-->
<TextBlock Text="Gueltigkeit: "/>
<TextBlock Text="{Binding Gueltigkeit}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</GroupBox>
MainWindow codebehind and ViewModel
public partial class QuarterPickerTest : UserControl
{
public QuarterPickerTest()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
}
public class ViewModel
{
public ViewModel()
{
this.Dummy = new Dummy { Gueltigkeit = DateTime.Today };
this.Dummies = new List<Dummy>
{
new Dummy {Gueltigkeit = DateTime.Today},
new Dummy {Gueltigkeit = DateTime.Today.AddMonths(6)},
new Dummy {Gueltigkeit = DateTime.Today.AddDays(-6)},
};
}
public Dummy Dummy { get; set; }
public List<Dummy> Dummies { get; set; }
}
Here is the code behind of my UserControl
#region SelectedFirstDay
public DateTime SelectedFirstDay
{
get { return (DateTime)GetValue(SelectedFirstDayProperty); }
set { SetValue(SelectedFirstDayProperty, value); }
}
public static readonly DependencyProperty SelectedFirstDayProperty
= DependencyProperty.Register("SelectedFirstDay", typeof (DateTime), typeof (QuarterPicker),
new FrameworkPropertyMetadata(DateTime.Today, SelectedFirstDayPropertyChangedCallback) { BindsTwoWayByDefault = true });
private static void SelectedFirstDayPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
var quarterPicker = dependencyObject as QuarterPicker;
var date = (DateTime)args.NewValue;
var quarter = GetQuarter(date);
quarterPicker.UpdateProperties(date.Year, quarter);
if (date.Year == quarterPicker.LeftInfiniteYear && quarter == quarterPicker.LeftInfiniteQuarter)
quarterPicker.ShowPopupButtonLeftInfinite();
}
#endregion
Thanks for any suggestions!
Related
I am working on an executive dashboard that should be able to have any number of charts each with any number of series. I am using the WPF Toolkit.
The first problem I had was binding multiple series to a chart. I found Beat Kiener's excellent blogpost on binding multiple series to a chart which worked great until I put it in an items control, which I have to do to meet my "any number of charts" requirement.
It seems to me that the below code should work, but it does not. Can anyone explain why the below code does not work, or offer another way to do it using MVVM?
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public ChartData ChartData { get; set; }
public List<ChartData> ChartDataList { get; set; }
public MainWindow()
{
var dataSeries = new Dictionary<string, int>();
dataSeries.Add("Jan", 5);
dataSeries.Add("Feb", 7);
dataSeries.Add("Mar", 3);
ChartData = new ChartData();
ChartData.Title = "Chart Title";
ChartData.DataSeriesList = new List<Dictionary<string, int>>();
ChartData.DataSeriesList.Add(dataSeries);
ChartDataList = new List<ChartData>();
ChartDataList.Add(ChartData);
InitializeComponent();
this.DataContext = this;
}
}
public class ChartData
{
public string Title { get; set; }
public List<Dictionary<string, int>> DataSeriesList { get; set; }
}
MainWindow.xaml
<UniformGrid
Rows="1">
<!-- These charts do not work -->
<ItemsControl
x:Name="itemsControl"
ItemsSource="{Binding ChartDataList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:MultiChart
Title="{Binding Title}"
SeriesSource="{Binding DataSeriesList}">
<local:MultiChart.SeriesTemplate>
<DataTemplate >
<chartingToolkit:ColumnSeries
Title="Series Title"
ItemsSource="{Binding}"
IndependentValueBinding="{Binding Key}"
DependentValueBinding="{Binding Value}"/>
</DataTemplate>
</local:MultiChart.SeriesTemplate>
</local:MultiChart>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- End of not working charts -->
<!-- This chart works -->
<local:MultiChart
Title="{Binding ChartData.Title}"
SeriesSource="{Binding ChartData.DataSeriesList}">
<local:MultiChart.SeriesTemplate>
<DataTemplate>
<chartingToolkit:ColumnSeries
Title="Series Title"
ItemsSource="{Binding}"
IndependentValueBinding="{Binding Key}"
DependentValueBinding="{Binding Value}" />
</DataTemplate>
</local:MultiChart.SeriesTemplate>
</local:MultiChart>
<!-- End of working chart -->
</UniformGrid>
MultiChart.cs
public class MultiChart : System.Windows.Controls.DataVisualization.Charting.Chart
{
#region SeriesSource (DependencyProperty)
public IEnumerable SeriesSource
{
get
{
return (IEnumerable)GetValue(SeriesSourceProperty);
}
set
{
SetValue(SeriesSourceProperty, value);
}
}
public static readonly DependencyProperty SeriesSourceProperty = DependencyProperty.Register(
name: "SeriesSource",
propertyType: typeof(IEnumerable),
ownerType: typeof(MultiChart),
typeMetadata: new PropertyMetadata(
defaultValue: default(IEnumerable),
propertyChangedCallback: new PropertyChangedCallback(OnSeriesSourceChanged)
)
);
private static void OnSeriesSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
IEnumerable oldValue = (IEnumerable)e.OldValue;
IEnumerable newValue = (IEnumerable)e.NewValue;
MultiChart source = (MultiChart)d;
source.OnSeriesSourceChanged(oldValue, newValue);
}
protected virtual void OnSeriesSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
this.Series.Clear();
if (newValue != null)
{
foreach (object item in newValue)
{
DataTemplate dataTemplate = null;
if (this.SeriesTemplate != null)
{
dataTemplate = this.SeriesTemplate;
}
// load data template content
if (dataTemplate != null)
{
Series series = dataTemplate.LoadContent() as Series;
if (series != null)
{
// set data context
series.DataContext = item;
this.Series.Add(series);
}
}
}
}
}
#endregion
#region SeriesTemplate (DependencyProperty)
public DataTemplate SeriesTemplate
{
get
{
return (DataTemplate)GetValue(SeriesTemplateProperty);
}
set
{
SetValue(SeriesTemplateProperty, value);
}
}
public static readonly DependencyProperty SeriesTemplateProperty = DependencyProperty.Register(
name: "SeriesTemplate",
propertyType: typeof(DataTemplate),
ownerType: typeof(MultiChart),
typeMetadata: new PropertyMetadata(default(DataTemplate))
);
#endregion
}
I finally figured it out.
When you put the MultiChart inside of an ItemsControl the SeriesSource property is set BEFORE the SeriesTemplate property. This does not work because the OnSeriesSourceChanged method needs to know what the SeriesTemplate is. My workaround is to just call the OnSeriesSourceChanged method whenever the SeriesTemplate is changed.
private static void OnSeriesTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DataTemplate oldValue = (DataTemplate)e.OldValue;
DataTemplate newValue = (DataTemplate)e.NewValue;
MultiChart source = (MultiChart)d;
source.OnSeriesTemplateChanged(oldValue, newValue);
}
protected virtual void OnSeriesTemplateChanged(DataTemplate oldValue, DataTemplate newValue)
{
this.SeriesTemplate = newValue;
OnSeriesSourceChanged(SeriesSource, SeriesSource);
}
public static readonly DependencyProperty SeriesTemplateProperty = DependencyProperty.Register(
name: "SeriesTemplate",
propertyType: typeof(DataTemplate),
ownerType: typeof(MultiChart),
typeMetadata: new PropertyMetadata(
defaultValue: default(DataTemplate),
propertyChangedCallback: new PropertyChangedCallback(OnSeriesTemplateChanged)
)
);
I have a UserControl with ComboBox.
<ComboBox Grid.Row="8" Grid.Column="1"
VerticalAlignment="Center"
x:Name="cmbCategory"
ItemsSource="{Binding ElementName=ucAppiGeneralInfo, Path=Categories, Mode=TwoWay}"
SelectedItem="{Binding ElementName=ucAppiGeneralInfo, Path=SelectedCategory, Mode=TwoWay}"
IsEditable="True"
IsSynchronizedWithCurrentItem="True"
SelectedValuePath="CAT_ID"
TextSearch.TextPath="CAT_NAME">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=CAT_NAME}"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding Path=PUBLIC_DESCRIPTION}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The code behind is:
public partial class AppiGeneralInfoUC : UserControl
{
public DataTable Categories
{
get { return (DataTable)GetValue(CategoriesProperty); }
set { SetValue(CategoriesProperty, value);}
}
public static readonly DependencyProperty CategoriesProperty =
DependencyProperty.Register(
"Categories",
typeof(DataTable),
typeof(AppiGeneralInfoUC),
new UIPropertyMetadata(null));
public String SelectedCategory
{
get { return (String)GetValue(SelectedCategoryProperty); }
set
{
SetValue(SelectedCategoryProperty, value);
}
}
public static readonly DependencyProperty SelectedCategoryProperty =
DependencyProperty.Register(
"SelectedCategory",
typeof(String),
typeof(AppiGeneralInfoUC),
new UIPropertyMetadata(null));
public AppiGeneralInfoUC()
{
InitializeComponent();
}
}
I have a window which use the UserControl:
<TabControl>
<TabItem Header="Information">
<my:AppiGeneralInfoUC x:Name="ucAppiGeneralInfo"
Categories="{Binding Path=Categories, Mode=TwoWay}"
SelectedCategory="{Binding Path=SelectedCategory, Mode=TwoWay}" />
</TabItem>
the code behind is:
public partial class ApplicationWindow : Window
{
VMBase appiGeneralInfoWin = new AppiGeneralInfoVM();
public ApplicationWindow()
{
InitializeComponent();
ucAppiGeneralInfo.DataContext = appiGeneralInfoWin;
}
public void updateAction(string cat_id)
{
this.Title = "Update application";
(appiGeneralInfoWin as AppiGeneralInfoVM).setSelectedCategory(cat_id);
} ...
And finally I have ViewModel class:
class AppiGeneralInfoVM : VMBase
{
private DataTable categories = null;
private String selectedCategory = null;
public DataTable Categories
{
get { return this.categories; }
set
{
this.categories = value;
this.OnPropertyChanged("Categories");
}
}
public String SelectedCategory
{
get { return this.selectedCategory; }
set
{
this.selectedCategory = value;
this.OnPropertyChanged("SelectedCategory");
}
}
public AppiGeneralInfoVM()
{
ServicesLoader.LoadRunTimeServices();
Categories = GetService<CategoryBLL>().getCategories();
}
public void setSelectedCategory(string cat_id)
{
SelectedCategory = Categories.Select("cat_id =" + "'"+cat_id+"'")[0]["CAT_NAME"].ToString();
}
Everything works well but i have problem with the selectedItem (SelectedCategory),
it's not update at all....
I think it happens because your SelectedItem has string type while your collection is DataTable (which enumerates DataRow). Try changing your collection to be IEnumerable<string>
today I getting crazy while trying to do, what I think, is simple thing.
I want to be able to create my usercontrol, and use it in my column template in my datagrid
I have searched and tried several combinations, and nothing appear to work
Can anyone help me?
public class User
{
public string Name { get; set; }
public bool IsValid { get; set; }
}
partial class MyControl : UserControl
{
private string _value;
public string Value
{
get { return _value; }
set { _value = value;
txt.Text = value;
}
}
public MyControl()
{
InitializeComponent();
}
}
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock x:Name="txt" Text="[undefined]"></TextBlock>
</Grid>
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
var items = new List<User>();
items.Add(new User{Name = "user 1", IsValid = true});
items.Add(new User { Name = "user 2", IsValid = false });
myGrid.ItemsSource = items;
}
}
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid x:Name="myGrid" AutoGenerateColumns="False" IsReadOnly="True">
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn Header="Name">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<SilverlightApplication1:MyControl Value="{Binding Name}"></SilverlightApplication1:MyControl>
<!--<TextBlock Text="{Binding Name}"></TextBlock>-->
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
Edited:
I also tried the following, but I get no results on my grid:
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock x:Name="txt" Text="{Binding Value}"></TextBlock>
</Grid>
public partial class MyControl : UserControl
{
public DependencyProperty ValueProperty =
DependencyProperty.Register("Value",
typeof(string),
typeof(MyControl),
new PropertyMetadata(OnValueChanged));
public string Value
{
get
{
return (string)GetValue(ValueProperty);
}
set
{
SetValue(ValueProperty, value);
NotifyPropertyChanged("Value");
}
}
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyControl) d).Value = (String)e.NewValue; //ERROR: here I got always empty string
}
public MyControl()
{
InitializeComponent();
}
}
The reason why your first code didn't work is simple. To be able to bind the "Value" property on your "MyControl" (Value={Binding Name}), it has to be a Dependency Property. which you fixed in your second bit of code.
Here's what I did (and that worked well):
<UserControl x:Class="BusinessApplication8_SOF_Sandbox.Controls.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" Name="myControl">
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Name="textBlock" Text="{Binding Value, ElementName=myControl}"/>
</Grid>
</UserControl>
For the rest, I used your code.
Another possibility, which should be OK in case you only want the data to flow in one direction ("One Way" from source to target), as it is the case when using the TextBlock control is to update the Text property in the "OnValueChanged". here's the code for the Value property:
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string), typeof(MyControl),
new PropertyMetadata("", OnValueChanged));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (MyControl)d;
var oldValue = (string)e.OldValue;
var newValue = target.Value;
target.OnValueChanged(oldValue, newValue);
}
protected virtual void OnValueChanged(string oldValue, string newValue)
{
textBlock.Text = newValue;
}
and you can remove the binding in xaml:
<TextBlock Name="textBlock" />
this worked for me as well.
Hope this helps ;)
you need to implement the INotifyPropertyChanged interface in your User class so that bound user controls are aware if any of the bound properties change. See the following page with the details how to implement it : http://www.silverlightshow.net/tips/How-to-implement-INotifyPropertyChanged-interface.aspx
As you can see you need to implement the interface and in the setters raise the event OnPropertyChanged
Then it should work with your bindings.
Best,
Tim
Can you bind to a local variable like this?
SystemDataBase.cs
namespace WebWalker
{
public partial class SystemDataBase : Window
{
private string text = "testing";
...
SystemDataBase.xaml
<TextBox
Name="stbSQLConnectionString"
Text="{SystemDataBase.text}">
</TextBox>
??
Text is set to the local variable "text"
The pattern is:
public string Text {get;set;}
and the binding is
{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}
If you want the binding to update automatically you should make it a DependencyProperty.
I think 3.5 added ElementName to bindings, so the following is a little easier:
<Window x:Name="Derp" ...
<TextBlock Text="{Binding Text, ElementName=Derp}"/>
To bind to a local "variable" the variable should be:
A property, not a field.
Public.
Either a notifying property (suitable for model classes) or a dependency property (sutable for view classes)
Notifying property example:
public MyClass : INotifyPropertyChanged
{
private void PropertyType myField;
public PropertyType MyProperty
{
get
{
return this.myField;
}
set
{
if (value != this.myField)
{
this.myField = value;
NotifyPropertyChanged("MyProperty");
}
}
}
protected void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Dependency property example:
public MyClass : DependencyObject
{
public PropertyType MyProperty
{
get
{
return (PropertyType)GetValue("MyProperty");
}
set
{
SetValue("MyProperty", value);
}
}
// Look up DependencyProperty in MSDN for details
public static DependencyProperty MyPropertyProperty = DependencyProperty.Register( ... );
}
If you're doing a lot of this, you could consider binding the DataContext of the whole window to your class. This will be inherited by default, but can still be overridden as usual
<Window DataContext="{Binding RelativeSource={RelativeSource Self}}">
Then for an individual components you can use
Text="{Binding Text}"
To bind a local variable which is present in your Window class it has to be :
1. Public property
2. A notifying property. For this your window class should implement INotifyPropertyChanged interface for this property.
Then in the constructor
public Assgn5()
{
InitializeComponent();
this.DataContext = this; // or **stbSQLConnectionString**.DataContext = this;
}
<TextBox
Name="stbSQLConnectionString"
Text="{Binding text}">
</TextBox>
Need to add the following line in the int constructor:
this.DataContext = this;
And use this in the XAML:
<TextBox Text = "{Binding SomeProperty}" />
Exmaple:
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public string PersonName { get; set; }
public MainWindow()
{
InitializeComponent();
PersonName = "default";
this.DataContext = this;
}
void button1_Click(object sender, RoutedEventArgs args)
{
MessageBox.Show($"Hello {PersonName}");
}
}
MainWindow.xaml
<StackPanel>
<TextBox Name="textbox1"
Text="{Binding PersonName, Mode=TwoWay}"
/>
<Button Name="button1" Click="button1_Click" Content="Click Me" />
</StackPanel>
I am trying to successfully TwoWay bind an ObservableCollection to TextBoxes in a DataTemplate. I can get the data to display properly, but I am unable to change the list data through the UI. I have a Model class named 'model' which contains an ObservableCollection named 'List'. The class implements the INotifyPropertyChanged interface. Here is the xaml for the shell. The DataContext for Window1's grid is set to "theGrid.DataContext=model"
<Window x:Class="BindThat.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BindThat"
Title="Window1" Height="300" Width="300">
<StackPanel x:Name="theGrid">
<GroupBox BorderBrush="LightGreen">
<GroupBox.Header>
<TextBlock Text="Group" />
</GroupBox.Header>
<ItemsControl ItemsSource="{Binding Path=List}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</GroupBox>
</StackPanel>
This is the code for the Model class:
class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
private ObservableCollection<string> _list = new ObservableCollection<string>();
public ObservableCollection<string> List
{
get { return _list; }
set
{
_list = value;
NotifyPropertyChanged("List");
}
}
public Model()
{
List.Add("why");
List.Add("not");
List.Add("these?");
}
}
Could anyone advise if I am going about this the correct way?
You need a property to bind two way, so string is not good for this.
Wrap it in a string object, like this:
public class Model
{
public ObservableCollection<StringObject> List { get; private set; }
public Model()
{
List = new ObservableCollection<StringObject>
{
new StringObject {Value = "why"},
new StringObject {Value = "not"},
new StringObject {Value = "these"},
};
}
}
public class StringObject
{
public string Value { get; set; }
}
and bind to Value property instead of "."
Also, you don't need to notify of a change in observable collection, so until your model has some other propertis of its own, it does not need to have INotifyPropertyChange. If you want your ItemsControl react to changes in the individual StringObjects, then you should add INotifyPropertyChanged to a StringObject.
And yet again, two way binding is default, so you need only
<TextBox Text="{Binding Path=Value}" />
in your binding.
I believe you need to derive your collection items from DependencyObject for TwoWay binding to work. Something like:
public class DependencyString: DependencyObject {
public string Value {
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string), typeof(DependencyString), new UIPropertyMetadata(""));
public override string ToString() {
return Value;
}
public DependencyString(string s) {
this.Value = s;
}
}
public class Model {
private ObservableCollection<DependencyString> _list = new ObservableCollection<DependencyString>();
public ObservableCollection<DependencyString> List {
get { return _list; }
}
public Model() {
List.Add(new DependencyString("why"));
List.Add(new DependencyString("not"));
List.Add(new DependencyString("these?"));
}
}
...
<StackPanel x:Name="theGrid">
<GroupBox BorderBrush="LightGreen">
<GroupBox.Header>
<TextBlock Text="Group" />
</GroupBox.Header>
<ItemsControl ItemsSource="{Binding Path=List}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Value, Mode=TwoWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</GroupBox>
</StackPanel>
xaml view:
<ItemsControl ItemsSource="{Binding List}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
in code behind in the constructor:
DataContext = new ViewModel();
in ViewModel Class:
class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private ObservableCollection<StringObject> _List = new ObservableCollection<StringObject>();
public ObservableCollection<StringObject> List
{
get { return _List; }
set
{
_List = value;
NotifyPropertyChanged("List");
}
}
public ViewModel()
{
List = new ObservableCollection<StringObject>
{
new StringObject {Value = "why"},
new StringObject {Value = "not"},
new StringObject {Value = "these"}
};
}
}
public class StringObject
{
public string Value { get; set; }
}
Be careful with a collection with type string it doesn't work, you have to use an object => StringObject