如何将外集合属性的CommandParameter传递给WPF中的内部集合

时间:2016-02-04 11:37:40

标签: c# wpf data-binding path-finding commandparameter

我在这里有模型ObservableCollection的外MobileModel。 MobileModel的模型inner Collection

MobileModelInfo

我需要将OS的属性作为CommandParameter传递给Inner Collection。

C#源代码是

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);
    }

XAML源代码

<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>

如何在OS

中传递属性<Binding Path="DataContext"></Binding>

1 个答案:

答案 0 :(得分:2)

首先为MultiValueBinding创建一个转换器,将两个属性合并为一个Tuple,它将作为参数传递给您的命令:

 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();
    }
}

并将其添加到您的资源中:

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

多重绑定时使用该转换器。要获取Os属性和Selected MobileModelInfo,请使用RelativeSource绑定:

 <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>

你的命令看起来应该是这样的:

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
                }));
        }
    }