WPF UserControl公开内部列表项

时间:2009-09-09 14:57:55

标签: wpf data-binding user-controls

我正在尝试编写一个UserControl来显示一个项目列表,其中每个项目都是一个标题和一组复选框。整体将代表一种数据形式,填写它的人正在回答具有1到4值的问题列表。这一切都可以很好地与窗口的ViewModel绑定。

但我目前在UserControl中得到了如下硬编码的答案:

<ListBox
  ItemsPanel="{StaticResource HorizontalScores}"
  Style="{StaticResource styleOuterListBox}"
  ItemContainerStyle="{StaticResource styleOuterListBoxItem}">
  <ListBoxItem>Never</ListBoxItem>
  <ListBoxItem>Sometimes</ListBoxItem>
  <ListBoxItem>Often</ListBoxItem>
  <ListBoxItem>Always</ListBoxItem>
</ListBox>

我想从窗口的XAML或ViewModel中设置这些,因为它们对于其他表单会有所不同,但是看不到正确的咒语。如何从UserControl中删除ListBoxItems并使用数据绑定?

BigEdit ......

好的,这是实际的用户控件(它看起来很可怕,但这不是重点):

<UserControl x:Class="BussPerry.Scorer" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:BussPerry.ViewModel" xmlns:local="clr-namespace:BussPerry">

  <UserControl.Resources>

    <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="Gray" />
    <SolidColorBrush x:Key="SelectedForegroundBrush" Color="Red" />

    <ItemsPanelTemplate x:Key="HorizontalScores">
      <StackPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>

    <Style x:Key="styleListBox" TargetType="{x:Type ListBox}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListBox}">
            <ItemsPresenter Margin="2" />
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

    <Style x:Key="styleListBoxItem" TargetType="{x:Type ListBoxItem}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListBoxItem}">
            <CheckBox Name="CheckBox" Padding="1" Width="60" 
                          IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
              <ContentPresenter HorizontalAlignment="Center"/>
            </CheckBox>
            <ControlTemplate.Triggers>
              <Trigger Property="IsSelected" Value="True">
                <Setter TargetName="CheckBox" Property="Background" Value="{StaticResource SelectedBackgroundBrush}" />
                <Setter TargetName="CheckBox" Property="Foreground" Value="{StaticResource SelectedForegroundBrush}" />
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

  </UserControl.Resources>

  <ListBox ItemsPanel="{StaticResource HorizontalScores}" Style="{StaticResource styleListBox}" 
      ItemContainerStyle="{StaticResource styleListBoxItem}" SelectedIndex="{Binding Path=Score}">
    <ListBoxItem>Never</ListBoxItem>
    <ListBoxItem>Sometimes</ListBoxItem>
    <ListBoxItem>Often</ListBoxItem>
    <ListBoxItem>Always</ListBoxItem>
  </ListBox>

</UserControl>

它被称为如下:

<ListView
  Name="listviewScores"
  ItemsSource="{Binding Path=Scores}"

  Margin="5"
  BorderThickness="0"
  Background="Transparent"
  Focusable="False"
  Grid.Row="3">
  <ListView.View>
    <GridView
      ColumnHeaderContainerStyle="{StaticResource styleHiddenHeader}">
      <GridView.Columns>

        <GridViewColumn>
          <GridViewColumn.CellTemplate>
            <DataTemplate>
              <TextBlock
                Text="{Binding Path=Index}"
                HorizontalAlignment="Right" />
              </DataTemplate>
          </GridViewColumn.CellTemplate>
        </GridViewColumn>

        <GridViewColumn
          DisplayMemberBinding="{Binding Path=Title}" />

        <GridViewColumn >
          <GridViewColumn.CellTemplate>
            <DataTemplate>
              <local:Scorer >
              </local:Scorer>
            </DataTemplate>
          </GridViewColumn.CellTemplate>
        </GridViewColumn>
      </GridView.Columns>
    </GridView>
  </ListView.View>

</ListView>

我想要做的是将Never / Sometimes / often / Always listboxitems从用户控件中硬编码为数据绑定。

(也欢迎你提出“你不想这样做”的建议!)

2 个答案:

答案 0 :(得分:1)

(一年后......)

我认为你的问题与我的问题类似。我想出了一种技术来公开UserControl上内部控件的ItemsSource。我的问题的链接在这里:

Exposing inner Control properties for binding in WPF

我知道我的解决方案有效。我不知道的是,它是否违反了WPF中一些神圣的“最佳实践”。虽然感觉很好。

答案 1 :(得分:0)

是否要将集合绑定到列表框?

这很简单......

<ListBox ItemsSource="{Binding Answers}" />

其中Answers是您在ViewModel中公开的集合。

如果您在创建公开ItemsSource的自定义控件时遇到问题,那么您只需要继承ItemsControl而不仅仅是UserControl。

编辑:   一些假设:

  • 将ListBox的DataContext,自定义控件或更高的父元素设置为您的 视图模型。
  • ViewModel有一个 属性称为“答案”。
  • Answers属性实现 IEnumerable的&LT;&GT;
相关问题