Disabled button when textbox is empty in silverlight mvvm? - asp.net

i'm working on silverlight with MVVM pattern. in design page i have three textbox and one button. here my requirement is if the 3 textbox is empty or null means the button is disabled.
how to achieve this.. any help..?

Create a public property in your VM that checks the conditions you've stated above and returns a Boolean accordingly. Bind this property to your button IsEnabled property.
Make sure to fire PropertyChangedEvent once every condition status is changed (i.e in the textbox changed event).

Here i have attached my coding..
Xaml:
<Button Content="Add" Width="59" IsEnabled="{Binding ButtonIsEnabled}" Height="23" Margin="256,75,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" TabIndex="4" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<si:CallDataMethod Method="AddEmployee"/>
<si:SetProperty TargetName="LayoutRoot" PropertyName="Background" Value="LightBlue"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<TextBlock FontWeight="Bold" Height="26" HorizontalAlignment="Left" Margin="47,12,0,0" Name="textBlock1" Text="First Name:" VerticalAlignment="Top" Width="77" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="130,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Fname,Mode=TwoWay}" TabIndex="1" AcceptsReturn="False">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<si:CallDataMethod Method="ButtonIsEnabled"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBlock FontWeight="Bold" Height="25" HorizontalAlignment="Left" Margin="35,44,0,0" Name="textBlock2" Text="Second Name:" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="130,44,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" Text="{Binding Sname,Mode=TwoWay}" TabIndex="2" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<si:CallDataMethod Method="ButtonIsEnabled"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBlock FontWeight="Bold" Height="23" HorizontalAlignment="Left" Margin="45,75,0,0" Name="textBlock3" Text="Department:" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="130,75,0,0" Name="textBox3" VerticalAlignment="Top" Width="120" Text="{Binding Dept,Mode=TwoWay}" TabIndex="3" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<si:CallDataMethod Method="ButtonIsEnabled"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
ViewModel Code:
EmployeeListViewModel.cs
public bool ButtonIsEnabled
{
get
{
return !(((string.IsNullOrEmpty(this.Fname)) && (string.IsNullOrEmpty(this.Sname)) && (string.IsNullOrEmpty(this.Dept))));
}
}
private string _fname;
public string Fname
{
get
{
return _fname;
}
set
{
if (_fname != value)
{
_fname = value;
RaisePropertyChanged("Fname");
//RaisePropertyChanged("ButtonIsEnabled");
}
else
{
_fname = value;
RaisePropertyChanged("Fname");
}
}
}
private string _sname;
public string Sname
{
get
{
return _sname;
}
set
{
if (_sname != value)
{
_sname = value;
RaisePropertyChanged("Sname");
RaisePropertyChanged("ButtonIsEnabled");
}
else
{
_sname = value;
RaisePropertyChanged("Sname");
}
}
}
private string _dept;
public string Dept
{
get
{
return _dept;
}
set
{
if (_dept != value)
{
_dept = value;
RaisePropertyChanged("Dept");
RaisePropertyChanged("ButtonIsEnabled");
}
else
{
_dept = value;
RaisePropertyChanged("Dept");
}
}
}
My Problem is:
1) It is worked for the 1st textbox. while i entered anything in the 1st textbox the button is in disabled mode. But if i moved to the 2nd TextBox means the button is enabled.
2) I need all the textbox will Validated after that only Button is enabled. If any one of the Textbox is Empty means the button is again went to disabled mode..
Any Help..?

If you are using Silverlight 5 then there is a very nice solution of MultiBinding through custom markup extensions: MultiBinding in Silverlight 5.
There is also an IMultiValueConverter which allows you to convert collection of binded values to single value (in your case - bool). Using both extension and converter you can easily achieve desired functionality.

Related

How to hide keyboard of entry inside the listview in xamarin.forms.ios

How to hide keyboard of an entry.I have an entry inside of a listview. When I tap on the entry the keyboard is showing, but the keyboard is not hiding when I tap outside. The listview row is adding dynamically so in first case only one row is in it.Android is working perfectly. But in iOS this issue is there.
Please help me
<ListView HorizontalOptions="FillAndExpand" ItemsSource="_list"
VerticalOptions="FillAndExpand"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation=Horizontal>
<Label Text="Name"/>
<Entry PlaceHolder="Name" />
<Label Text="+" FontSize="50">
<Label .GestureRecognizers>
<TapGestureRecognizer Tapped="AddMore_Tapped"
CommandParameter="{Binding Id}"/>
</Label .GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Xaml.CS
private async void AddMore_Tapped(object sender, EventArgs e)
{
_list.Add("1");
}
here is my code,
first time only one row is there after clicking the "+" icon one row will be added to listview. So in the case of listview with one row, when I tap on that entry the keyboard is showing, but when I tap outside it's not hiding.It's hiding only when I tap on the first row.
You could update your Xamarin.forms version to the last.
In ios, the keyboard would hide when you click on the other place of listview except the “+” label.
Or you could use custom renderer to make the done button, to hide the keyboard manually.
CustomEntry:cs
public class CustomEntry : Entry
{
}
CustomEntryRenderer.cs
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace HidekeyboardOfEntryDemo.iOS
{
public class CustomEntryRenderer : EntryRenderer
{
private UITextField textField;
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
textField = (UITextField)this.Control;
textField.ReturnKeyType = UIReturnKeyType.Done;
}
}
}
Usage
<hidekeyboardofentrydemo:CustomEntry Placeholder="Name" />
You could download HidekeyboardOfEntryDemo project from GitHub for reference.
https://github.com/WendyZang/Test.git

How to identify what itemSelected during button click inside ListBox ItemTemplate

I have an ItemTemplate that contains a simple button. When I click this button I need a way to identify the row clicked to pull out the item bound to the listbox.
XAML
<ListBox Name="DemoBox" SelectionChanged="listBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="150">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Height="120" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Text="{Binding SomeObjProperty}"/>
</Grid>
<Grid Height="120" Grid.Column="1" Margin="0,-12,0,0">
<Button Click="ShowStuffOnMap_Click">
<Button.Background>
<ImageBrush ImageSource="images/arrow.png"/>
</Button.Background>
</Button>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
click handler
private void ShowStuffOnMap_Click(object sender, RoutedEventArgs e)
{
//sender is the button so ...
}
Thank you in advance
Why do you have Button with a click event inside a ListBox with a SelectionChanged event? This makes up for some scary UX, if they have different actions!
The normal approach is to have a databound ListBox, and then use the SelectionChanged event to read out the selected item.
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = sender as ListBox;
var selectedItem = listBox.SelectedItem as MyDataBoundType;
if (selectedItem != null)
{
// do stuff
}
// if you use the ListBox for navigation, set the SelectedIndex to -1
// listBox.SelectedIndex = -1;
}
But if you really really want to do it, you need to use the Tag property.
<Button Click="ShowStuffOnMap_Click" Tag="{Binding}">
And then in your event handler:
private void ShowStuffOnMap_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
var selectedItem = button.Tag as MyDataBoundType;
}
But I still think your approach here is wrong, and stands for bad user experience, as the normal approach to a list is that the entire line in the list, is one-selection only.
The best way to do this is to have some unique identifier in the template itself. For example, you have a TextBlock - give it a unique name, and when the button is pressed, search the secondary grid for the TextBlock with the identifier and read its Text property.

Can't change Foreground in DataGridTextColumn

So, this is my Datagrid
<DataGrid AutoGenerateColumns="false" Height="270" HorizontalAlignment="Left" Name="dataGrid1" VerticalAlignment="Top" Width="503" ItemsSource="{Binding Path=MyVocabularyExam, Mode=TwoWay}" CanUserAddRows="False" CanUserResizeColumns="False" CanUserReorderColumns="False" CanUserSortColumns="False" SelectionMode="Single" SelectionUnit="Cell" >
<DataGrid.Columns>
<DataGridTextColumn x:Name="Sprache1" Width="*" Header="Sprache1" Binding="{Binding Language1}" IsReadOnly="True" />
<DataGridTextColumn x:Name="Sprache2" Width="*" Header="Sprache2" Binding="{Binding Language2, Mode=TwoWay}" IsReadOnly="False" Foreground="{Binding LanguageColor}"/>
</DataGrid.Columns>
</DataGrid>
I´m binding a List to the Datagrid with following Properties
public class myVocabulary
{
public string Language1 { get; set; }
public string Language2 { get; set; }
public SolidColorBrush LanguageColor { get; set; }
}
Now I want to make an Vocabulary Exam. The first column is filled with words and the other Column have to be filled with the translation.
My only problem is, I can´t change the foreground of the wrong translations, which the user have typed.
After the user have filled the grid, he have to click on a button, which will check if everything is correct. The wrong words have to turn in a red color.
I have tried
MyVocabularyExam[i].LanguageColor = Brushes.Red;
MyVocabularyExam[i].LanguageColor = new SolidColorBrush(Colors.Red);
But that didn´t work.
So please someone help me ^^
I had to set ElementStyle explicitly to make it work:
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground"
Value="{Binding Path=FontColor}"></Setter>
</Style>
</DataGridTextColumn.ElementStyle>
Maybe there is a better solution, but I stopped searching at this point.

silverlight datagrid multicontrol TemplateColumn TabIndex issue

In SL4 DataGrid I have the following multicontrol column:
<sdk:DataGridTemplateColumn Header="Address Line1
Address Line 2" MinWidth="200">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Address1}"/>
<TextBlock Text="{Binding Path=Address2}"/>
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel>
<TextBox Background="Transparent" BorderThickness="0"
TabIndex="0"
Text="{Binding Path=Address1, Mode=TwoWay}"/>
<TextBox Background="Transparent" BorderThickness="0"
TabIndex="1"
Text="{Binding Path=Address2, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
</sdk:DataGridTemplateColumn>
In edit mode pressing Tab key while at address1 moves focus to next DataGrid column but not to address2 textbox. If I delete CellTemplate and CellEditingTemplate to be CellTemplate instead, then TabIndex works as expected, however, current column stay the same, so if datagrid has many columns, some of which are hidden, then auto scrolling doesn't occur. What should I do to solve this problem?
A little bit late, but i found a workaround for this problem.
Just add a KeyDown EventHandler to your CustomControl:
private void address1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key.Equals(Key.Tab) && address2.IsEnabled)
{
address2.Focus();
e.Handled = true;
}
}
Probably, having multiple controls inside datagrid cell is bad idea. If multiple controls needs to be inside cell, then better way seems to be to create custom composite control and place it inside cell.

how to capture the "Menu Item 1" text in the dropdown button and assign to textbox

I am using a code snippet from codeproject of dropdown button.
< m:SplitButton Content="TWB" Name="btnSearch"
Grid.Row="0" Grid.Column="0"
Style="{StaticResource aeroNormalColorSplitButtonStyle}"
Click="btnSearch_Click"
Width="60" Height="30"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Mode="{Binding ElementName=modeSelector, Path=SelectedItem}"
Placement="{Binding ElementName=placementSelector, Path=SelectedItem}" MouseLeftButtonDown="btnSearch_MouseLeftButtonDown"
MenuItem Header="TWB"/>
MenuItem Header="PWB">
/MenuItem>
</m:SplitButton>
so, beside this splitdown button, I have a textbox(which is basically a search box). So, as the above code snippet shows the 2 menu items as "TWB" and "PWB", I have to fill the textbox when TWB is selected from the dropdown button and also the same text should be displayed on the button too (TWB).
if i click PWB from the dropdownbutton, I should get the "PWB" name on the button and the same PWB name should be displayed in the textbox too.
Please help me.
Thank You,
Ramm
I tried by adding ListBox to the SplitButton, Now I am able to see the text in the textbox.
Modified the above Xaml code to
<m:SplitButton Content="TWB" Name="btnSearch"
Grid.Row="0" Grid.Column="0"
Style="{StaticResource aeroNormalColorSplitButtonStyle}"
Click="btnSearch_Click"
Width="60" Height="30"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Mode="{Binding ElementName=modeSelector, Path=SelectedItem}"
Placement="{Binding ElementName=placementSelector, Path=SelectedItem}">
<ListBox x:Name="TransitionKind" SelectionChanged="TransitionKind_SelectionChanged">
<ListBoxItem Content="TWB"/>
<ListBoxItem Content="PWB"/>
</ListBox>
</m:SplitButton>
in the code behind,
btnSearch.Click += new RoutedEventHandler(btnSearch_Click);
TransitionKind.SelectionChanged += new System.Windows.Controls.SelectionChangedEventHandler(TransitionKind_SelectionChanged);
private void TransitionKind_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
btnSearch.Content = ((ListBoxItem)TransitionKind.SelectedItem).Content;
txtBxSearch.Text = "Search " + (string) btnSearch.Content;
}
Now, I am able to see the text in the textbox changing to the click of dropdown button.
Thank you,
Ramm

Resources