使用 IEnumerable collection 在 Item 模板内绑定 ComboBox

ComboBox binding inside Item template with IEnumerable collection

我有一个 class MovieSystem 继承自 AvailableMoviescollection.

public class MovieSystem  : IEnumerable<AvailableMovies >, IEnumerable
{
    public AvailableMovies this[int i] { get; }
    public AvailableMovies this[TheatreLocation location] { get; }
    public AvailableMovies [] ReleasedMovies { get; }
 }

TheatreLocation 是一个枚举,其值类似于

public enum TheatreLocation 
{
        Citycentre = 0,
        CityNorth = 1,
        CitySouth = 2,
        CityEast = 3,
        CityWest = 4,
}

AvailableMovies collection 具有以下属性

public class AvailableMovies 
{
        public AvailableMovies ();
        public int Index { get; }
        public TheatreLocation Location { get; set; }
        public string TheatreID { get; set; }
        public double Ticketprice{ get; }
}

我的 Xaml 代码如下所示

<ItemsControl ItemsSource="{Binding MovieSystem  }">            
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                            <ComboBox 
                                      ItemsSource="{Binding Path= ""What should I bind here? ""}"
                                      DisplayMemberPath="{Binding Path = ???}"
                                      SelectedIndex="{Binding Path =Location , Mode=TwoWay, Converter={StaticResource MovieSystemLocationConverter}}">
                            </ComboBox>
                            <ComboBox
                                      ItemsSource="{Binding Path = ???}"
                                      SelectedIndex="{Binding Path=TheatreID , Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                      DisplayMemberPath="{Binding Path= ??}">
                            </ComboBox>
                            <TextBox Grid.Column="3"
                                     Text="{Binding Path= Ticketprice, Mode =TwoWay,StringFormat=F3, NotifyOnValidationError=True}"/>
                                    
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
</ItemsControl>

我有一个视图模型,xaml数据上下文设置为这个视图模型。

internal class MovieSystemPanelViewModel
{
        ///tried this collection but not worked.
        public ObservableCollection<LocationViewModel> Locations { get; } = new ObservableCollection<LocationViewModel>();
   
        public MovieSystem MovieSystem { get; }
              
        public MovieSystemPanelViewModel() {}
}

现在我的问题是应该显示剧院 ID 的 ComboBox 和由于绑定问题而没有显示的位置。如果尝试将 Locations observable collection 绑定到 ComboBox itemsource 中,这是不允许的,在 items 模板中只有 AvailableMovies 属性处于可绑定状态。 票价已正确绑定并显示。

这里的问题是因为您将 Items.Control 与集合绑定,所以 Items.Control 的子元素将只能访问该集合的 属性。所以,如果你想使用另一个集合,你需要使用 relative source 来获得 datacontext 级别的访问权限。由于它是 enum 才能正确显示,因此您需要使用扩展方法显示字典值,并在 ComboBox 中使用另一个 Itemtemplate 以获得正确显示。

internal class MovieSystemPanelViewModel
{
        ///Use  dictionary instead of observable collection
        public Dictionary<TheatreLocation , string> Locations { get; } = new Dictionary<TheatreLocation , string>();
   
        public MovieSystem MovieSystem { get; };
              
        public MovieSystemPanelViewModel() 
        {
            // Fill up data in dictionary
            foreach (Enum item in Enum.GetValues(typeof(TheatreLocation)))
            {
                Locations.Add((TheatreLocation)item, ((TheatreLocation)item).GetDisplayName());
            }
        }
}

在项目某处写一个Extension方法,根据需要显示成员。

public static string GetDisplayName(this TheatreLocation location)
{
            switch (location)
            {
                case TheatreLocation.CityCentre:
                    return "Center city location";

                case TheatreLocation.CityNorth :
                    return "Northern city location";

                case TheatreLocation.CitySouth :
                    return "Southern city location";

                case TheatreLocation.CityEast :
                    return "Eastern city location";

                case CameraLocation.CityWest :
                    return "Western city location";

                 default:
                    return "Unknown";
            }
}

现在使用这些属性和方法绑定 xaml

<ComboBox 
         ItemsSource="{Binding Path= DataContext.Locations, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
          SelectedIndex="{Binding Path =Location , Mode=TwoWay, Converter={StaticResource MovieSystemLocationConverter}}">
            <ComboBox.ItemTemplate>
                  <DataTemplate>
                             <TextBlock Text="{Binding Path=Value}" />
                   </DataTemplate>
              </ComboBox.ItemTemplate>
</ComboBox>