Wednesday, August 29, 2012

Silverlight datagrid show or hide controls with combobox selection

Silverlight datagrid show or hide controls with combobox selection

To make shorter, let's say I have a Datagrid with a combobox a TextBox, and another Combobox. I'd like to show or hide the text or the combobox according to the value selected with the first Combo

               <sdk:DataGridTemplateColumn.CellTemplate>                                             <DataTemplate>                                                 <Grid>                                                     <Grid.ColumnDefinitions>                                                         <ColumnDefinition />                                                         <ColumnDefinition/>                                                     </Grid.ColumnDefinitions>                                                     <ComboBox x:Name="cboThenConstOrCol" SelectedIndex="0" SelectedItem="{Binding Source={StaticResource VM}, Path=cboElseSelectedItem, Mode=TwoWay}">                                                         <ComboBoxItem Content="None"/>                                                         <ComboBoxItem Content="Const" />                                                         <ComboBoxItem Content="Col"/>                                                     </ComboBox>                                                     <TextBox Grid.Column="1" Text="{Binding ElseConst}" Visibility="{Binding Source={StaticResource VM}, Path= IsVisibleElseConst}" IsTabStop="{Binding Source={StaticResource VM}, Path=isElseConstTabStop}"></TextBox>                                                     <ComboBox Grid.Column="1" ItemsSource="{Binding Source={StaticResource VM}, Path=Fields,Mode=OneWay}" Visibility="{Binding Source={StaticResource VM}, Path= IsVisibleElseCol}" DisplayMemberPath="FieldName" />                                                 </Grid>                                             </DataTemplate>                                         </sdk:DataGridTemplateColumn.CellTemplate> 

in my Viewmodel i'm taking care of showing or hiding and is working correctly, but the problem is when I make the textbox visible all textbox in all Rows become visible. What I'd like to to is just apply to the row where the combobox selecteditem has been changed. I hope i was clear, otherwise please let me know to add additional info. thanks

Answers & Comments...

Answer: 1

From what I can gather you've got one ViewModel that controls everything. I think you'll run into problems doing this, and while it may seem easier doing things like this at first it definitely isn't when any amount of complexity is introduced. What I'd do is embrace MVVM a bit more and make a ViewModel for the item that each of your Rows represent. This allows each row to maintain it's own state. Here's an example based on what you've provided:

Modified XAML (incomplete):

<UserControl.Resources>     <local:VM         x:Key="vm" /> </UserControl.Resources> <Grid     DataContext="{StaticResource vm}"     x:Name="LayoutRoot"     Background="White">     <sdk:DataGrid         AutoGenerateColumns="False"         ItemsSource="{Binding Items}">         <sdk:DataGrid.Columns>             <sdk:DataGridTemplateColumn>                 <sdk:DataGridTemplateColumn.CellTemplate>                     <DataTemplate>                         <Grid>                             <Grid.ColumnDefinitions>                                 <ColumnDefinition                                     Width="100" />                                 <ColumnDefinition />                             </Grid.ColumnDefinitions>                             <ComboBox                                 ItemsSource="{Binding Source={StaticResource vm}, Path=Options}"                                 SelectedItem="{Binding Selected, Mode=TwoWay}" />                             <TextBox                                 Grid.Column="1"                                 Text="Else"                                 Visibility="{Binding TextVisible}" />                         </Grid>                     </DataTemplate>                 </sdk:DataGridTemplateColumn.CellTemplate>             </sdk:DataGridTemplateColumn>         </sdk:DataGrid.Columns>     </sdk:DataGrid> </Grid> 

Items is collection containing 'ItemViewModel's. The major change here is that the bindings in the data template now map to properties of 'ItemViewModel'. The exception to this is the ComboBox's ItemSource (which contains your 'None', 'Const' and 'Col' values), which binds to the Main VM.

Main VM:

public class VM : INotifyPropertyChanged {     private readonly ObservableCollection<ItemViewModel> items = new ObservableCollection<ItemViewModel>();     private readonly ObservableCollection<string> options = new ObservableCollection<string>();      public ObservableCollection<ItemViewModel> Items { get { return items; } }     public ObservableCollection<string> Options { get { return options; } }      public VM()     {       options.Add("None");       options.Add("Const");       options.Add("Col");              //Create some dummy items       for (int i = 0; i < 10; i++)       {         var item = new ItemViewModel();         item.Name = i.ToString();         item.Selected = options[0];         items.Add(item);       }     }     //INotifyPropertyChanged stuff    

Item VM:

public class ItemViewModel : INotifyPropertyChanged {     private string selected;     private Visibility textVisible;      public string Selected     {       get { return selected; }       set       {         if (!string.IsNullOrWhiteSpace(value))         {           switch (value.ToLower())           {             case "none":               TextVisible = Visibility.Collapsed;               break;             case "const":               TextVisible = Visibility.Visible;               break;             case "col":               TextVisible = Visibility.Visible;               break;           }        }          selected = value;        }     }      public Visibility TextVisible     {       get { return textVisible; }       set       {         textVisible = value;         RaisePropertyChanged("TextVisible");       }     }      //INotifyPropertyChanged stuff         } 

You can see here that when the selected value is changed for this item, some logic is run to determine whether the text should be visible or not.

There's a few things wrong with this but hopefully it gets you on the right path.

by : wdavohttp://stackoverflow.com/users/807836




No comments:

Post a Comment

Send us your comment related to the topic mentioned on the blog