I have a problem for WPF assoccolation
GridViewColumn Values to Combobox Items Values
I'm using enum objects for Fill to combobox.
Can't binding GridItemColumn(durum) to ComboboxItems
ENUM
[TypeConverter(typeof(EnumDescriptionTypeConverter))]
public enum eViziteDurumlari
{
[Description("Onaysız")]
Onaysiz = 0,
[Description("Onaylı")]
Onayli = 1,
[Description("Hepsi")]
Hepsi = 99
}
[TypeConverter(typeof(EnumDescriptionTypeConverter))]
public enum eViziteDurum
{
[Description("Onaysız")]
Onaysiz = 0,
[Description("Onaylı")]
Onayli = 1,
}
ENUM CLASSES
public class EnumDescriptionTypeConverter : EnumConverter
{
public EnumDescriptionTypeConverter(Type type)
: base(type)
{
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
if (value != null)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
if (fi != null)
{
var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return ((attributes.Length > 0) && (!String.IsNullOrEmpty(attributes[0].Description))) ? attributes[0].Description : value.ToString();
}
}
return string.Empty;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
public class EnumBindingSourceExtension : MarkupExtension
{
private Type _enumType;
public Type EnumType
{
get { return this._enumType; }
set
{
if (value != this._enumType)
{
if (null != value)
{
Type enumType = Nullable.GetUnderlyingType(value) ?? value;
if (!enumType.IsEnum)
throw new ArgumentException("Type must be for an Enum.");
}
this._enumType = value;
}
}
}
public EnumBindingSourceExtension() { }
public EnumBindingSourceExtension(Type enumType)
{
this.EnumType = enumType;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (null == this._enumType)
throw new InvalidOperationException("The EnumType must be specified.");
Type actualEnumType = Nullable.GetUnderlyingType(this._enumType) ?? this._enumType;
Array enumValues = Enum.GetValues(actualEnumType);
if (actualEnumType == this._enumType)
return enumValues;
Array tempArray = Array.CreateInstance(actualEnumType, enumValues.Length + 1);
enumValues.CopyTo(tempArray, 1);
return tempArray;
}
}
DATA TABLE
private DataTable DataTableOlustur()
{
Islemler = null;
using (Islemler = new DataTable())
{
Islemler.Columns.Add("firmaadi", typeof(string));
Islemler.Columns.Add("firmakodu", typeof(string));
Islemler.Columns.Add("tckimliknr", typeof(string));
Islemler.Columns.Add("adisoyadi", typeof(string));
Islemler.Columns.Add("bas_istirahat", typeof(DateTime));
Islemler.Columns.Add("bit_istirahat", typeof(DateTime));
Islemler.Columns.Add("durum", typeof(int));
return Islemler;
}
return null;
}
XAML
<ListView x:Name="lstItems">
<ListView.View>
<GridView x:Name="gridView" ScrollViewer.CanContentScroll="True" TextSearch.Text="True">
<GridViewColumn Width="120" Header="Firma Kodu" DisplayMemberBinding="{Binding firmakodu}"/>
<GridViewColumn Width="220" Header="Firma Adı" DisplayMemberBinding="{Binding firmaadi}" />
<GridViewColumn Width="120" Header="TC Kimlik No" DisplayMemberBinding="{Binding tckimliknr}"/>
<GridViewColumn Width="auto" Header="Adı Soyadı" DisplayMemberBinding="{Binding adisoyadi}" />
<GridViewColumn Width="120" Header="İstirahat Baş. Tarihi" DisplayMemberBinding="{Binding bas_istirahat,StringFormat={}{0:dd/MM/yyyy}}" />
<GridViewColumn Width="120" Header="İstirahat Bit. Tarihi" DisplayMemberBinding="{Binding bit_istirahat,StringFormat={}{0:dd/MM/yyyy}}" />
<GridViewColumn Header="Durum">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="150"
ItemsSource="{Binding Source={local:EnumBindingSource {x:Type local:eViziteDurum}}}"
SelectedValue="{Binding Path=durum}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I can't see DataTable Values to Combobox
I'm sorry for bad english
The ComboBox.ItemsSource is filled with enum values and it will not auto-convert the SelectedValue between int and the enum type, so a converter is needed there.
Code:
public class EnumIntegerConverter : IValueConverter
{
// probably add some code to ensure the enum type is actually set
// or move it to the converter parameter in order to use the same converter instance with different types
public Type EnumType { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// probably add some sanety checks on the involved types and values
return Enum.ToObject(EnumType, value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// probably add some sanety checks on the involved types and values
return System.Convert.ToInt32(value);
}
}
XAML resource
<local:EnumIntegerConverter x:Key="enumConverter" EnumType="{x:Type local:eViziteDurum}"/>
XAML usage
<ComboBox ... SelectedValue="{Binding Path=durum,Converter={StaticResource enumConverter}}"/>
Related
what is a best way to bind enum property to datagrid.currently i am using public property and return enum name from there is there any other way ?
Enumeration
public enum enStatus
{
Draft = 1,
Published = 2,
Started = 3,
Completed = 4
}
Model
class ModelA
{
private int statudId;
public string Status { get { return Enum.GetName(typeof(enStatus),statudId); }
}
DataGrid
<DataGrid Name="dataGrdAssignments" Style="{StaticResource dataGridManageScreens}" SelectedCellsChanged="dataGrdAssignments_SelectedCellsChanged">
<DataGrid.Columns>
<DataGridTextColumn Header="Status" Width="150" Binding="{Binding Status}" ElementStyle="{StaticResource gridElementStyle}" EditingElementStyle="{StaticResource gridEditElementStyle}">
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
Your approach works, but I'd prefer cleaning up your ViewModel by using a binding converter instead.
public class EnumConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((Enum)value).ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
And in your XAML, something like this:
Binding="{Binding Status, Converter="{StaticResource ResourceKey=enumConverter}}"
Don't forget to declare your "enumConverter" (or however you'll decide to name it) in the resources section of your xaml file.
class EnumToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return loai.ToDisplaytring();
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
<ListView ItemsSource="{Binding ListEnum" Margin="0,51,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=.,Converter={StaticResource EnumToStringConverter}}" HorizontalAlignment="Center" FontSize="18"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I am a new guy to XAML.
I just want to display enum in listview.
But it has some problem of binding itself with binding:
{Binding Path=.,Converter={StaticResource EnumToStringConverter}}
This is simpler:
<ListView x:Name="ListViewInstance" ItemsSource="{Binding ListEnum}" Margin="0,51,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" HorizontalAlignment="Center" FontSize="18"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
That's the binding that gets the items, it automatically makes the item.ToString()
and to show all the values in the DataContext, for instance:
public List<Devices> ListEnum { get { return typeof(Devices).GetEnumValues().Cast<Devices>().ToList(); } }
In case you need a converter do the following:
public class EnumToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return what you need to convert from value
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
and then in XAML
<Window.Resources>
<local:EnumToStringConverter x:Key="EnumToStringConverter"/>
</Window.Resources>
<ListView x:Name="ListViewInstance" ItemsSource="{Binding ListEnum}" Margin="0,51,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding, Converter={StaticResource EnumToStringConverter}}" HorizontalAlignment="Center" FontSize="18"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You can use the enum with attributes and the create a list for listbox using extension methods.You can refer the below code.
<ListBox Width="200" Height="25" ItemsSource="{Binding ComboSource}"
DisplayMemberPath="Value"
SelectedValuePath="Key"/>
public class MainViewModel
{
public List<KeyValuePair<RentStatus, string>> ComboSource { get; set; }
public MainViewModel()
{
ComboSource = new List<KeyValuePair<RentStatus, string>>();
RentStatus re=RentStatus.Active;
ComboSource = re.GetValuesForComboBox<RentStatus>();
}
}
public enum RentStatus
{
[Description("Preparation description")]
Preparation,
[Description("Active description")]
Active,
[Description("Rented to people")]
Rented
}
public static class ExtensionMethods
{
public static List<KeyValuePair<T, string>> GetValuesForComboBox<T>(this Enum theEnum)
{
List<KeyValuePair<T, string>> _comboBoxItemSource = null;
if (_comboBoxItemSource == null)
{
_comboBoxItemSource = new List<KeyValuePair<T, string>>();
foreach (T level in Enum.GetValues(typeof(T)))
{
string Description = string.Empty;
FieldInfo fieldInfo = level.GetType().GetField(level.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
Description = attributes.FirstOrDefault().Description;
}
KeyValuePair<T, string> TypeKeyValue = new KeyValuePair<T, string>(level, Description);
_comboBoxItemSource.Add(TypeKeyValue);
}
}
return _comboBoxItemSource;
}
}
I try to connect two checkboxes to my ViewModel. Their behavior is like a radiobutton (exclusive) and TheeState. So both not checked or one of them checked
At the moment I am doing the job like that:
<dxlc:LayoutGroup>
<dxlc:LayoutItem Label="with errors">
<CheckBox IsChecked="{Binding OnlyMusicWithErrorsChecked}"></CheckBox>
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="without errors">
<CheckBox IsChecked="{Binding OnlyMusicWithoutErrorsChecked}"></CheckBox>
</dxlc:LayoutItem>
</dxlc:LayoutGroup>
und ViewModel:
private bool _onlyMusicWithErrorsChecked;
public bool OnlyMusicWithErrorsChecked
{
get { return _onlyMusicWithErrorsChecked; }
set
{
SetProperty(ref _onlyMusicWithErrorsChecked, value, () => OnlyMusicWithErrorsChecked);
if (OnlyMusicWithErrorsChecked)
OnlyMusicWithoutErrorsChecked = false;
RaisePropertyChanged("AdditionalCriteriaHeader");
if (!_filteringData)
SelectData();
}
}
private bool _onlyMusicWithoutErrorsChecked;
public bool OnlyMusicWithoutErrorsChecked
{
get { return _onlyMusicWithoutErrorsChecked; }
set
{
SetProperty(ref _onlyMusicWithoutErrorsChecked, value, () => OnlyMusicWithoutErrorsChecked);
if (OnlyMusicWithoutErrorsChecked)
OnlyMusicWithErrorsChecked = false;
RaisePropertyChanged("AdditionalCriteriaHeader");
if (!_filteringData)
SelectData();
}
}
The question is: can I use only one property nullable bool to do this job?
You can bind both CheckBoxes to the same property OnlyMusicWithErrorsChecked, and in the second CheckBox add a converter that inverts the property's value:
<CheckBox IsChecked="{Binding OnlyMusicWithErrorsChecked, Converter={StaticResource Inverter}}"></CheckBox>
This converter would look somewhat like:
public class Inverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool)
return !((bool)value);
else // Fallback
return false;
}
}
EDIT: If you want to build a three-state-solution with only one bindable property, you'll need two converters (or one that can be parameterized):
public class MyConverter : DependencyObject, IValueConverter
{
public static readonly DependencyProperty InvertProperty = DependencyProperty.Register(
"Invert", typeof (bool), typeof (MyConverter), new PropertyMetadata(default(bool)));
public bool Invert
{
get { return (bool) GetValue(InvertProperty); }
set { SetValue(InvertProperty, value); }
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var val = (bool?) value;
switch (val)
{
case true:
return Invert;
break;
case false:
return !Invert;
break;
case null:
return false; // None of the checkboxes shall be active
break;
}
// Fallback
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var val = (bool)value;
switch (val)
{
case true:
return Invert;
break;
case false:
return null;
break;
}
// Fallback
return false;
}
}
The Invert property is set to false for the first checkbox, and true for the second one:
<Window.Resources>
<local:MyConverter x:Key="Converter" Invert="False"/>
<local:MyConverter x:Key="Inverter" Invert="True"/>
</Window.Resources>
Now you can use these two converter instances to bind the checkboxes to the same property:
<CheckBox IsChecked="{Binding MyProperty, Converter={StaticResource Converter}}" />
<CheckBox IsChecked="{Binding MyProperty, Converter={StaticResource Inverter}}" />
If the first box is checked the property will be false, if the second one is checked it will be true, and if no checkbox is checked it will be null.
However, I agree with ANewGuyInTown that you'd be better off with an Enum, since the bool types are a bit confusing here (by the way, most of the converter can be re-used when working with a three-state enum instead of nullable boolean).
Make a "NotConverter" on one of the checkboxes. Here's my implementation I've been using for a while in Windows Store and Phone apps. WPF is similar.
/// <summary>
/// Converts a bool to it's oppisite and back.
/// </summary>
public sealed class NotConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return (!(value is bool)) || !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return (value is bool) && (bool)value;
}
}
Register your converter in your App.xaml (or your view) file:
<Application.Resources>
<ResourceDictionary>
<converters:NotConverter x:Key="NotConverter"/>
</ResourceDictionary>
</Application.Resources>
Bind it in your view:
<CheckBox IsChecked="{Binding OnlyMusicWithErrorsChecked,Converter={StaticResource NotConverter}}"></CheckBox>
You could also name your other checkbox and bind to it's property like this:
<CheckBox x:Name="MyCheckBox" IsChecked="{Binding OnlyMusicWithErrorsChecked}"/>
<CheckBox IsChecked="{Binding ElementName=MyCheckBox,Path=IsChecked,Converter={StaticResource NotConverter}}"/>
Three state checkbox.
public bool CheckBox1
{
get { return _checkBox1; }
set
{
_checkBox1 = value;
if (value == true)
{
CheckBox2 = false;
}
OnPropertyChanged("CheckBox1");
}
}
private bool _checkBox2 = false;
public bool CheckBox2
{
get { return _checkBox2; }
set
{
_checkBox2 = value;
if (value == true)
{
CheckBox1 = false;
}
OnPropertyChanged("CheckBox2");
}
}
In Xaml Code something like this
<CheckBox Content="CheckBox1" IsChecked="{Binding CheckBox1, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Height="30" Width="100" />
<CheckBox Content="CheckBox2" IsChecked="{Binding CheckBox2, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Height="30" Width="100" />
I'm getting this error:
Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an
exception.
With xaml code:
<WrapPanel Orientation="Horizontal" Grid.Row="0" >
<WrapPanel.Visibility>
<Binding Path="setVisible" Converter="{StaticResource BooleanToVisibilityConverter}" ConverterParameter="{Binding setVisible}"/>
</WrapPanel.Visibility>
//textblocks goes here
</WrapPanel>
and class:
public class dataTemplate_xItem
{
(...)
public bool setVisible { get; set; }
public sealed class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var flag = false;
if (value is bool)
{
flag = (bool)value;
}
else if (value is bool?)
{
var nullable = (bool?)value;
flag = nullable.GetValueOrDefault();
}
if (parameter != null)
{
if (bool.Parse((string)parameter))
{
flag = !flag;
}
}
if (flag)
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible));
if (parameter != null)
{
if ((bool)parameter)
{
back = !back;
}
}
return back;
}
}
}
And before i'm adding item to ListView, checking
if(myValue != 0)
newItem.setVisible = true;
else
newItem.setVisible = false;
Any idea what goes wrong? :)
icebat is correct. The ConverterParameter is not a DependencyProperty and therefore, cannot be bound to. Looking at your xaml, you do not need the ConverterParameter. Nor do you need the extended markup for the binding expression. You xaml can simply be
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="Boolean2Visibility" />
</UserControl.Resources>
<WrapPanel Orientation="Horizontal" Grid.Row="0" Visibility="{Binding Path=setVisible, Converter={StaticResource Boolean2Visibility}}" />
This code assumes you are in a UserControl
Does anyone know if there is an option to hide a GridViewColumn somehow like this:
<ListView.View>
<GridView>
<GridViewColumn Header="Test" IsVisible="{Binding Path=ColumnIsVisible}" />
</GridView>
<ListView.View>
Thanks a lot!
Edit: For clarity
Unfortunately, there is no "IsVisible" Property. I'm looking for a way to create that.
Edit: The solution based on the feedback looks like:
<GridViewColumn DisplayMemberBinding="{Binding Path=OptionColumn1Text}"
Width="{Binding Path=SelectedEntitiy.OptionColumn1Width}">
<GridViewColumnHeader Content="{Binding Path=SelectedEntitiy.OptionColumn1Header}" IsEnabled="{Binding Path=SelectedEntitiy.OptionColumn1Width, Converter={StaticResource widthToBool}}" />
</GridViewColumn>
public class WidthToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value > 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Thanks to all!
Cheers
Edit: Reflecting the modified question.
What about creating a 0 width column? Write a Boolean to Width IValueConverter, that takes a ColumnIsVisible as the ConverterParmeter?
public class BooleanToWidthConverter : IValueConverter {
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture){
return ((bool) parameter)? value : 0;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture){
throw new NotImplementedException();
}
}
Something like:
<ListView .. >
<ListView.Resources>
<BooleanToWidthConverter x:Key="boolToWidth" />
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn
Header="Test"
Width=
"{Binding Path=ColumnWidth,
Converter={StaticResource boolToWidth},
ConverterParameter=ColumnIsVisible}" />
</GridView>
<ListView.View>
Here is another solution based on setting the column's width to zero. I have modified it a little. It now works like this:
Bind the header's visibility to a boolean property of the ViewModel, using a bool-to-visibility converter
Use an attached property on the header to set the column's width to zero
Here is the code.
XAML:
<GridViewColumn
HeaderTemplate="..."
HeaderContainerStyle="...">
<GridViewColumnHeader
Content="Header text"
Visibility="{Binding AppliesToColumnVisible, Converter={StaticResource BooleanToVisibilityConverter}}"
behaviors:GridViewBehaviors.CollapseableColumn="True" />
BooleanToVisibilityConverter:
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool param = bool.Parse(value.ToString());
if (param == true)
return Visibility.Visible;
else
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Attached behavior GridViewBehaviors.CollapseableColumn:
public static readonly DependencyProperty CollapseableColumnProperty =
DependencyProperty.RegisterAttached("CollapseableColumn", typeof(bool), typeof(GridViewBehaviors),
new UIPropertyMetadata(false, OnCollapseableColumnChanged));
public static bool GetCollapseableColumn(DependencyObject d)
{
return (bool)d.GetValue(CollapseableColumnProperty);
}
public static void SetCollapseableColumn(DependencyObject d, bool value)
{
d.SetValue(CollapseableColumnProperty, value);
}
private static void OnCollapseableColumnChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
GridViewColumnHeader header = sender as GridViewColumnHeader;
if (header == null)
return;
header.IsVisibleChanged += new DependencyPropertyChangedEventHandler(AdjustWidth);
}
static void AdjustWidth(object sender, DependencyPropertyChangedEventArgs e)
{
GridViewColumnHeader header = sender as GridViewColumnHeader;
if (header == null)
return;
if (header.Visibility == Visibility.Collapsed)
header.Column.Width = 0;
else
header.Column.Width = double.NaN; // "Auto"
}
One simpler approach, that still uses the concept of setting the columns width to zero but does not have the side effects of using a IValueConverter (the user can still drag the column wider) is to create a new getter/setter that returns a width based on your ColumnIsVisible variable and then bind to that:
public double ColumnWidth
{
get
{
if (this.ColumnIsVisible)
{
return 100;
}
else
{
return 0;
}
}
set
{
OnPropertyChanged("ColumnWidth");
}
}
Make your bindings TwoWay and if the user attempts to drag the column wider OnPropertyChanged will be called and reset the width to 0. You might have to use a binding proxy though for your binding. Also add a call to OnPropertyChanged("ColumnWidth") when ever ColumnIsVisible is updated :)
I've set the column the width="0".
Now the column looks like its not visible. But i do not know if it will affect anything else.
It might be a dummy solution but for now it works.
Use if Thumb.DragDelta may solve the problem
I use it in listview as
<ListView x:Name="MyListView"IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Path=Items}", Mode=Default, Source={StaticResource DataProvider}}"
Thumb.DragDelta="Thumb_DragDelta">
public Window1()
{
InitializeComponent();
MyListView.AddHandler(Thumb.DragDeltaEvent, new DragDeltaEventHandler(Thumb_DragDelta), true );
void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
Thumb senderAsThumb = e.OriginalSource as Thumb;
GridViewColumnHeader header = senderAsThumb.TemplatedParent as GridViewColumnHeader;
if (header.Column.ActualWidth < MIN_WIDTH)
{
header.Column.Width = MIN_WIDTH;
}
if (header.Column.ActualWidth > MAX_WIDTH)
{
header.Column.Width = MAX_WIDTH;
}
}
}