1

Here I'm having Outer ObservableCollection of model MobileModel. The MobileModel has an inner Collection of model MobileModelInfo

I need to Pass the Property of OS as a CommandParameter which is inside the Inner Collection.

The C# Source Code is

public class MobileModel : Notify
{
    private string _brand = string.Empty;
    private ObservableCollection<MobileModelInfo> _model = new ObservableCollection<MobileModelInfo>();
    private string _os = string.Empty;

    public string Brand
    {
        get { return _brand; }
        set { _brand = value; OnPropertyChanged(); }
    }
    public ObservableCollection<MobileModelInfo> Model
    {
        get { return _model; }
        set { _model = value; OnPropertyChanged(); }
    }

    public string OS
    {
        get { return _os; }
        set { _os = value; OnPropertyChanged(); }
    }
}

public class MobileModelInfo
{
    public string Name { get; set; }
    public bool IsMobileSelected { get; set; }
}

public void GetMobile()
    {
        List<MobileModel> mList = new List<MobileModel>();
        List<MobileModelInfo> modList = new List<MobileModelInfo>();
        MobileModel mob = new MobileModel();

        modList.Clear();
        mob.Brand = "Apple";
        modList.Add(new MobileModelInfo { Name = "iPhone 4" });
        modList.Add(new MobileModelInfo { Name = "iPhone 5" });
        modList.Add(new MobileModelInfo { Name = "iPhone 6" });
        mob.Model = new ObservableCollection<MobileModelInfo>(modList);
        mob.OS = "IOS";
        mList.Add(mob);

        mob = new MobileModel();
        modList.Clear();
        mob.Brand = "Samsung";
        modList.Add(new MobileModelInfo { Name = "S4" });
        modList.Add(new MobileModelInfo { Name = "S5" });
        modList.Add(new MobileModelInfo { Name = "S6" });
        mob.Model = new ObservableCollection<MobileModelInfo>(modList);
        mob.OS = "Android";
        mList.Add(mob);

        mob = new MobileModel();
        modList.Clear();
        mob.Brand = "MicroSoft";
        modList.Add(new MobileModelInfo { Name = "Lumina 9900" });
        modList.Add(new MobileModelInfo { Name = "Opera X220" });
        mob.Model = new ObservableCollection<MobileModelInfo>(modList);
        mob.OS = "Windows";
        mList.Add(mob);

        mob = new MobileModel();
        modList.Clear();
        mob.Brand = "Sony Ericssion";
        modList.Add(new MobileModelInfo { Name = "S4" });
        modList.Add(new MobileModelInfo { Name = "S5" });
        modList.Add(new MobileModelInfo { Name = "S6" });
        mob.Model = new ObservableCollection<MobileModelInfo>(modList);
        mob.OS = "Android";
        mList.Add(mob);

        MobileList = new ObservableCollection<MobileModel>(mList);
    }

The XAML Source Code

<ListBox Name="MobieDetail" ItemsSource="{Binding MobileList}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Name="Brand" Width="200"/>
                        <ColumnDefinition Name="Mobile" Width="90"/>
                        <ColumnDefinition Name="OS" Width="120"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Brand}" MaxWidth="195" TextWrapping="Wrap"  Grid.Column="0"/>
                <ComboBox Name="MobileName" ItemsSource="{Binding Model,UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Width="220" HorizontalAlignment="Left" VerticalAlignment="Center">
                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <CheckBox x:Name="ChkSelect" Content="{Binding Name}" IsChecked="{Binding IsMobileSelected}">
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="Checked">
                                        <commandHelper:EventToCommand Command="{Binding ElementName=MobieDetail, Path=MobieDetailCommand}">
                                            <commandHelper:EventToCommand.CommandParameter>
                                                <MultiBinding>
                                                    <Binding Path="DataContext"></Binding>
                                                    <Binding ></Binding>
                                                </MultiBinding>
                                            </commandHelper:EventToCommand.CommandParameter>
                                        </commandHelper:EventToCommand>
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </CheckBox>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                    <TextBlock Text="{Binding OS}" MaxWidth="195" TextWrapping="Wrap"  Grid.Column="2"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

How to Pass the Property OS within the <Binding Path="DataContext"></Binding>

B.Balamanigandan
  • 4,713
  • 11
  • 68
  • 130
  • So to the MobieDetailCommand you need to pass two information as a command parameter : (a MobileModelInfo object and the OS property) ? is that what are you looking for ? – SamTh3D3v Feb 04 '16 at 13:21

1 Answers1

2

First of all create a converter for your MultiValueBinding that will combine the two properties into one Tuple, that will be passed as a parameter to your Command:

 public class CombineTupletConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values==null)            
            return null;
        return new Tuple<object,object>(values[0],values[1]);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

and add it to your resources:

  <Window.Resources>
    <YourNameSpace:CombineTupletConverter x:Key="CombineTupletConverter"/>
</Window.Resources>

Use that converter when multi binding. To get the Os property and the Selected MobileModelInfo, use RelativeSource Binding :

 <ComboBox Name="MobileName" ItemsSource="{Binding Model,UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Width="220" HorizontalAlignment="Left" VerticalAlignment="Center">
                        <ComboBox.ItemTemplate>
                            <DataTemplate>
                                <CheckBox x:Name="ChkSelect" Content="{Binding Name}" IsChecked="{Binding IsMobileSelected}">
                                    <i:Interaction.Triggers>
                                        <i:EventTrigger EventName="Checked">
                                            <commandHelper:EventToCommand Command="{Binding ElementName=MobieDetail, Path=DataContext.MobieDetailCommand}">
                                                <commandHelper:EventToCommand.CommandParameter>
                                                    <MultiBinding Converter="{StaticResource CombineTupletConverter}">
                                                        <Binding Path="DataContext" RelativeSource="{RelativeSource AncestorType={x:Type CheckBox}}"></Binding>
                                                        <Binding Path="DataContext.OS" RelativeSource="{RelativeSource AncestorType={x:Type ComboBox}}"></Binding>                                                            
                                                    </MultiBinding>
                                                </commandHelper:EventToCommand.CommandParameter>
                                            </commandHelper:EventToCommand>
                                        </i:EventTrigger>
                                    </i:Interaction.Triggers>
                                </CheckBox>
                            </DataTemplate>
                        </ComboBox.ItemTemplate>
                    </ComboBox>

Your command should look something like that:

private RelayCommand<Tuple<object,object>> _mobieDetailCommand;
    public RelayCommand<Tuple<object, object>> MobieDetailCommand
    {
        get
        {
            return _mobieDetailCommand
                ?? (_mobieDetailCommand = new RelayCommand<Tuple<object, object>>(
                (tuple) =>
                {
                    var mobileInfo=tuple.Item1 as MobileModelInfo;
                    var os=tuple.Item2.ToString();                        
                    //Your logic
                }));
        }
    }
SamTh3D3v
  • 9,854
  • 3
  • 31
  • 47