Checkboxes not checked despite value being true - c#

So I am having a problem with my column updating, as far as I can see it's updating fine but for some reason the actual checkboxes that should be getting checked aren't. I can't seem to figure out why as all the values are set as true.
using (IDbConnection connection = sessionFactory.ConnectionProvider.GetConnection())
{
if (TableExists(connection, "tbl_ecom_cat_feature") &&
ColumnExists(connection, "tbl_ecom_cat_feature", "display_on_search"))
{
using (IDbCommand cmd = connection.CreateCommand())
{
cmd.CommandText = "UPDATE tbl_ecom_cat_feature SET display_on_search = 1";
cmd.ExecuteNonQuery();
}
}
EDIT: I have just realised that in my Checkbox_Check method I haven't actually put anything in to check if it's checked... I'm actually unsure how I would grab the data from the SQL column to see if it's true and if it is, return the box as checked.
Code in which I display the checkboxes:
public class StringToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && value is string)
{
var input = (string)value;
if (string.IsNullOrEmpty("Name"))
{
return Visibility.Collapsed;
}
else
{
return Visibility.Visible;
}
}
return Visibility.Visible;
}
and the WPF code in which these checkboxes are displayed is as follows:
<GridViewColumn Header="Display On Search">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Visibility="{Binding StringToVisibilityConverter}" IsChecked="{Binding StringToVisibilityConverter}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>

You need to bind your properties to a value from your datacontext and then assign the converter in the binding, so it will convert your source value, to a target value. Code:
<GridViewColumn Header="Display On Search">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Visibility="{Binding sourceProp, Converter={StaticResource myStringToVisibilityConverter}}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
and your will need to specify your converter as a resource like:
<Window.Resources>
<con:StringToVisibilityConverter x:Key="myStringToVisibilityConverter" />
</Window.Resources>
the resource could also be set on another level in the XAML eg. the gridview.

Related

Getting Control of RadioButton WPF

Here what i have in xaml:
<DataGrid Name="dataGrid">
<DataGridTemplateColumn Header = "Base" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<RadioButton Grid.Column="0" GroupName="{Binding Index}" Name="ABCD" Content="ABCD" IsChecked="True" Checked="radioButton_Checked"/>
<RadioButton Grid.Column="1" GroupName="{Binding Index}" Name="XYZ" Content="XYZ" Checked="radioButton_Checked" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid>
Here are some codes in some function (any) xaml.cs:
DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(i);
FrameworkElement radioButton = dataGrid.Columns[0].GetCellContent(row) as FrameworkElement;
radioButton.Visibility = Visibility.Hidden;
I can hide the visibility as I am hiding whole cell. but i want to change a radio button content in runtime from "XYZ" to "HAHAHA". How can i achieve this?
You might be able to use a value converter to achieve this. This can be used to change the name based on the index value;
public class IndexToXYZOrHaHaHaConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var index = (int) value;
if (index > 10)
{
return "XYZ";
}
return "HaHaHa";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
You'll need to create an instance of the class by adding a static resource to your resource dictionary.
<local:IndexToXYZOrHaHaHaConverter x:Key="IndexToXYZOrHaHaHaConverter"/>
You'll then need to change the content of the radio button from "xyz" to this;
Content="{Binding Index, Converter={StaticResource IndexToXYZOrHaHaHaConverter}}"
This should dynamically switch the value between xyz and HaHaHa depending on the index. In the example I gave this depends on whether the value is greater or less than 10, which is probably not what you want so you'll have to fix the logic. I've also assumed that index is an integer, you may need to change that too if index is something else.
Converters are great for setting properties based on bound values that don't directly correspond to the value they are bound to e.g. converting a string to a color.
Hope this is of some help.

WPF create object using IValueConverter with binding object's properties

my objects which I use to binding in XAML can have only string properties. But in binding I need other type. I thought that I use Converter function from IValueConverter, where I'll create object from string properties and return this. One property which is a string will be empty, and in binding I'll return other object from Converter method. I tried this but in Convert method my main object from ObservableCollection is null. This's a piece of my XAML
<Maps:MapItemsControl ItemsSource="{Binding}">
<Maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="Transparent" Tapped="ItemStckPanel">
<Image Source="/Assets/pushpin.gif" Height="30" Width="30"
Maps:MapControl.Location="{Binding Location,
Converter={StaticResource StringToGeopoint}}"
Maps:MapControl.NormalizedAnchorPoint="0.5,0.5"/>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5">
<TextBlock FontSize="20" Foreground="Black" Text="{Binding Name}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</Maps:MapItemsControl.ItemTemplate>
</Maps:MapItemsControl>
And this's my Convert method:
public object Convert(object value, Type targetType, object parameter, string language)
{
Event _event = (Event) parameter;
BasicGeoposition position = new BasicGeoposition();
position.Latitude = _event.Latitude;
position.Longitude = _event.Longitude;
return new Geopoint(position);
}
I want to pass the my actual parent object in Converter method. Solution is change
Maps:MapControl.Location="{Binding Location,
Converter={StaticResource StringToGeopoint}}"
to
Maps:MapControl.Location="{Binding Converter={StaticResource StringToGeopoint}}"
It works :)
The bound object is fed into the "value" parameter of the Convert()-Method.
You're accessing the parameter which corresponds to
<... ConverterParameter= .../>
which isn't set in your xaml.
You would actually have to write your Convert()-Method like this:
public object Convert(object value, Type targetType, object parameter, string language)
{
Event _event = (Event) value;
BasicGeoposition position = new BasicGeoposition();
position.Latitude = _event.Latitude;
position.Longitude = _event.Longitude;
return new Geopoint(position);
}
/UPDATE:
The ItemsSource={Binding} on your Maps:MapItemControl binds to the DataContext of the parent object. This should be your ObservableCollection.
Within the ItemTemplate your Image has a "Location"-Property that is bound to the "Location"-property of each item within your ObservableCollection. You could also write:
{Binding Path=Location, Converter={StaticResource StringToGeopoint}}
Now before that binding is fully evaluated, the Object that is stored in the Location-property is passed to the converter and the result is then handed to the "Location"-Property on the Image.
If you are getting null objects to be passed to the "value"-parameter, that means that the original Binding hands null values to the Converter either because the Property on the source object is null or because the property doesn't exist.

How to access my datagrid control in my viewmodel from view?

Hi guys I want to access my datagrid control in my viewmodel.I know this is the incorrect way but I have to do that:
<DataGrid
Grid.Row="1"
Margin="10,10,0,0"
Height="200"
Width="500"
Grid.ColumnSpan="2"
Name="dg"
HorizontalAlignment="Left"
AutoGenerateColumns="False"
ItemsSource="{Binding SSID}"
>
<DataGrid.Columns>
<DataGridTextColumn Width="100" Header="Network ID" Binding="{Binding _networkID}"></DataGridTextColumn>
<DataGridTextColumn Width="100" Header="SSID" Binding="{Binding _ssid}"></DataGridTextColumn>
<DataGridTextColumn Width="100" Header="VLAN" Binding="{Binding _vlan}"></DataGridTextColumn>
</DataGrid.Columns>
void AddSSIDs()
{
var ssid = new SSIDPropertyClass();
ssid._networkID = SSID.Count + 1;
ssid._ssid = EnteredSSIDAC;
ssid._vlan = VlanSSID;
if (ACSelectedSecurityType=="Static WEP")
{
ssid._authenticationMode = ACSelectedSecurityType;
ssid._authentication = ACStaticWEPSelectedAuthentication;
ssid._staticWEPKeyType = ACStaticWEPSelectedKeyType;
ssid._staticWEPKeyLength = ACStaticWEPSelectedKeyLength;
ssid._staticWEPKey1 = StaticWEPKey1;
ssid._staticWEPKey2 = StaticWEPKey2;
ssid._staticWEPKey3 = StaticWEPKey3;
ssid._staticWEPKey4 = StaticWEPKey4;
SSID.Add(ssid);
}
else if(ACSelectedSecurityType=="WPA/WPA2 Personal")
{
ssid._authenticationMode = ACSelectedSecurityType;
ssid._wpaPersonalKeyAC = WpaACKey;
SSID.Add(ssid);
}
}
I want to display only that columns in Datagrid which are selected in if blocks and else if blocks .If the condition of first if block is satisfies than all the other columns present inother else if blocks should be hidden. Please tell me the way in which I can access datagrid directly in ViewModel or any other way by which I can achieve the same thing.Any help would be highly appreciable.
You Can bind colunm visibility prop to your viewmodel prop:
<DataGridTextColumn Width="100" Header="Network ID" Binding="{Binding _networkID}" Visibility="{Binding NetworkVisibility}"></DataGridTextColumn>
<DataGridTextColumn Width="100" Header="SSID" Binding="{Binding _ssid}" Visibilty="{Binding SSIDVisible, Converter={StaticResource SSIDVisible}}"></DataGridTextColumn>
In ViewModel
public Visibility NetworkVisibility
{
get {
if(condition) return Visibility.Visible;
else return Visibility.Collapsed;
}
}
or you can do your viewmodel props of type bool, then just use BoolToVisibilityConverter in XAML
public bool SSIDVisible
{
get {
if(condition) return true;
else return false;
}
}
And for this props you can use NotifyPropertyChanged (if its supposed to change dynamically) as in Andrew Stephens answer.
You could create properties which contain information about the column selection status, for example a bool value, and bind them to the Visible property of your column. Use a converter to convert from bool to Visibility.
You could expose a couple of boolean properties from your VM, indicating which set of columns to display, then bind the Visibility property of each column to the relevant property. You'll need to use the BooleanToVisibilityConverter to convert the boolean value to a Visibility value (Visible or Collapsed). Something like this:-
<Window.Resources>
<BoolToVisibilityConverter x:Key="boolToVisConv" />
</Window.Resources>
<DataGridTextColumn Visibility="{Binding ShowWep, Converter={StaticResource boolToVisConv}" ... />
<DataGridTextColumn Visibility="{Binding ShowWpa, Converter={StaticResource boolToVisConv}" ... />
Edit (some VM code as requested)
Your VM class should implement INotifyPropertyChanged, and its property setters must raise the PropertyChanged event when the value changes. This ensures that anything in the view bound to a property reacts (e.g. refreshes) when its value changes. A typical example of the INPC interface can be found see here. Based on this code, the ShowWpa property would look something like this:-
public class MyViewModel
{
private bool _showWpa;
public bool ShowWpa
{
get
{
return _showWpa;
}
set
{
if (_showWpa != value)
{
_showWpa = value;
NotifyPropertyChanged("ShowWpa");
}
}
}
//etc..
}
A bad practise, but since you want it to be done that way..
Pass it as a parameter to the ViewModel from the code behind of the view.

Setting Image in ListView based on criteria

I'm doing a budgeting module.
I will like to ask that how to set the GridViewColumn to display out my desired image based on the value which I retrieve from database which are "income" & "expenses". I know how to retrieve the value from the database & display in the lisview but my question for today is that I will like to have some condition which is when found "income" will populate with income image then found expense will populate with another image???
Can this be possible. Hope to receive reply as soon as possible. Thank you.
I will provide my codes for better refer:
XAML file:
<DataTemplate x:Key="CategoriesType">
<Border BorderBrush="#FF000000" BorderThickness="1,1,0,1" Margin="-6,-2,-6,-2">
<StackPanel Margin="6,2,6,2">
<TextBlock Text="{Binding Path=CategoriesType}"/>
</StackPanel>
</Border>
</DataTemplate>
<Style x:Key="MyItemContainerStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<!--<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />-->
</Style>
</Window.Resources>
<ListView Height="320" HorizontalAlignment="Left" Margin="12,154,0,0" Name="CategoriesListView" VerticalAlignment="Top" Width="316" ItemsSource="{Binding}" ItemContainerStyle="{DynamicResource MyItemContainerStyle}">
<ListView.View>
<GridView>
<GridViewColumn Header="Types" Width="40" CellTemplate="{DynamicResource CategoriesType}"/>
</GridView>
</ListView.View>
</ListView>
Add an image tag in the tamplate and use a converter to return the correct image based on the string value (untested code)
xaml:
<UserControl.Resources>
<Converters:TypeToImageConverter x:Key="typeToImageConverter" />
</UserControl.Resources>
<StackPanel Margin="6,2,6,2">
<Image Source="{Binding Path=CategoriesType,Converter={StaticResource typeToImageConverter}"/>
<TextBlock Text="{Binding Path=CategoriesType}"/>
</StackPanel>
TypeToImageConverter.cs:
public class TypeToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
throw ...
var str = value.ToString();
if (str == "income")
return new BitmapImage(...);
if (str = "expenses")
return new BitmapImage(...);
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
I found the solution for my answer which is the format of the string. Which causing me to unavailable to retrieve the image with few hours of troubleshooting & debugging. I finally found out the solution :)
I solve it by like this:In my converter.cs
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
string str = (string)value;
string newString = str.TrimEnd();//Newly added compared with the old version
if (newString == "income")
return new BitmapImage(new Uri("pack://application:,,,/images/add.png"));
if (newString == "Expenses")
{
//return new BitmapImage(new Uri(#"pack://application:,,,/HouseWivesSavior;component/images/add.png"));
return new BitmapImage(new Uri("pack://application:,,,/images/edit.png"));
}
return null;
}
From referring the above that you can see that I added this code: "string newString = str.TrimEnd();"
Is because I don't want extra white space at the end of the string. As during insert into the database that my code is look like this:
if (IncomeButton.IsChecked == true) {
CategoryType = IncomeButton.Content.ToString();
}else{
CategoryType = ExpensesButton.Content.ToString();
}
During runtime, I found out that why the value look strange in the format of "Expenses " instead of "Expenses"... Therefore I tried with trim of the end part see how & Bingo. I got it working like a charm.
I refered this video to out that how to trace the value: http://www.youtube.com/watch?v=evO3_xutDYI
Thank you all guys for answering my question & sorry for wasting your time & effort to solve my question :) Good luck to all of you & have a nice day.

Failing To Bind Multiple UI Components in WPF

Alright I tried my best but looks like I need help. I have a textbox, a listview and a button in my xaml file. Listview has two columns: Devicename and DeviceAddress. I have done a binding of both the listview and textbox in such a way, that whenever I select an item in listview(I2CDeviceList), the deviceaddress(2nd Column) gets displayed in my textbox.
XAML:
<TextBox PreviewTextInput="AddressBox_PreviewTextInput" Name="AddressI2C" Text="{Binding SelectedItem.I2CDeviceAddress, Path=AddressMessage, Mode=TwoWay, ElementName=I2cDeviceList}" />
<Button Content="I2C Read" Command="{Binding Path=I2CReadCommand}" Name="button9" />
<ListView Grid.Column="0" ItemsSource="{Binding I2CDeviceList}" SelectedItem="{Binding SelectedI2CDeviceList, Mode=TwoWay}" Height="100" HorizontalAlignment="Stretch" Name="I2cDeviceList" VerticalAlignment="Stretch" Width="Auto" >
<ListView.View>
<GridView>
<GridViewColumn Header="I2C Device" Width="Auto" DisplayMemberBinding="{Binding I2CDevName}" />
<GridViewColumn Header="I2C Device Address" Width="Auto" DisplayMemberBinding="{Binding I2CDeviceAddress}" />
</GridView>
</ListView.View>
</ListView>
Thus using SelectedItem.I2CDeviceAddress gives me the deviceaddress in my Textbox.
Now my view model has a property for the Button and the textbox and has the following method which gets invoked when button is clicked:
public void I2CReadCommandExecuted()
{
ReadMessage = string.Empty;
Byte[] buffer = new Byte[512];
int address;
string strValue = AddressMessage;
if (strValue.StartsWith("0x"))
{
strValue = strValue.Remove(0, 2);
address = Convert.ToInt32(strValue);
mComm.setAddress(address);
}
}
// This is for textBox
private string _AddressMessage = string.Empty;
public string AddressMessage
{
get
{
return _AddressMessage;
}
set
{
_AddressMessage = value;
NotifyPropertyChanged("AddressMessage");
}
}
// Property for ListView
public ObservableCollection<I2CModel> I2CDeviceList
{
get { return _I2CDeviceList; }
set
{
_I2CDeviceList = value;
NotifyPropertyChanged("I2CDeviceList");
}
}
// Property for Selected Item in ListView
private I2CModel _selectedI2CDeviceList;
public I2CModel SelectedI2CDeviceList
{
get { return _selectedI2CDeviceList; }
set
{
_selectedI2CDeviceList = value;
NotifyPropertyChanged("SelectedI2CDevSize");
}
}
Basically I have to remove the 0x from the value and store the hexadecimal value in my integer variable.
Here I am facing two issues:
When I put both Text="{Binding SelectedItem.I2CDeviceAddress, Path=AddressMessage, Mode=TwoWay, ElementName=I2cDeviceList}" the seelcted address from the listview doesnt appear in my textbox. The moment I remove Path=AddressMessage, Mode=TwoWay,, it works fine. How to make sure both of them work smoothly? Is their any other way I can get the selected item from the listview and display it in my textbox?
By using string strValue = AddressMessage; I am trying to save the content of AddressMessage in the string but when I debug my code, it always shows "null" even though I have "0x23"(hardcoded) in my textbox. Due to this I get the following error: Object reference not set to an instance of an object. at the beginning of if condition.
I tried my level best but it ain't happening. Am i missing something?
First of all there is no need to have seperate AddressMessage property. It can be done using SelectedI2CDeviceList. But still if you want to use it it can be achieved through below changes -
Set AddressMessage property when the selected item of listview changes
public I2CModel SelectedI2CDeviceList
{
get { return _selectedI2CDeviceList; }
set
{
_selectedI2CDeviceList = value;
AddressMessage = _selectedI2CDeviceList.I2CDeviceAddress;
NotifyPropertyChanged("SelectedI2CDevSize");
}
}
Also change the binding of textbox to below one:
<TextBox
Name="AddressI2C"
Text="{Binding Path=AddressMessage, Mode=TwoWay}" />
Hence whenever selected item of the listview changes it will set the content for textbox and when AddressMessage property is properly set you want get your second issue.
Hope this helps.

Categories

Resources