2

我有一个ListBox绑定到一个ObesvableCollection动态创建的UserControls.

<ListBox x:Name="myListBox">
   <ListBox.Style>
      <Style TargetType="{x:Type ListBox}">
            <Setter Property="ItemsSource" Value="{Binding userControlsCollection}"/>
         ....
      </Style>
   </LIstBox.Style>
    <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <EventSetter Event="Selector.Selected" Handler="ListBox_Selected"/>
                    <EventSetter Event="Selector.Unselected" Handler="ListBox_UnSelected"/>
                    <Setter Property="Background" Value="{DynamicResource DefaultBackground}" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">

                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                                                      SnapsToDevicePixels="true"
                                                      Width="{Binding ActualWidth,RelativeSource={RelativeSource FindAncestor,AncestorType=ListBoxItem,AncestorLevel=1}}"
                                                      Height="{Binding ActualHeight,RelativeSource={RelativeSource FindAncestor,AncestorType=ListBoxItem, AncestorLevel=1}}"                                                      
                                                      />                                
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                 </Style>
</ListBox>

我想设置所选控件的背景应该是这样的

<Style.Triggers>
    <Trigger Property="IsSelected" Value="True">
        <Setter Property="Background" Value="{DynamicResource SelectedBackground}"/>
    </Trigger>
</Style.Triggers>

但这样我设置ListBoxItem Background它并不会传播用户控件背景......

我现在解决它的方法是使用这样的 Selector.Selected/UnSelected 事件处理程序

private void ListBox_Selected(object sender, RoutedEventArgs e)
    {

        var item = e.Source as ListBoxItem;
        var ctrl= item.Content as myControl;

        if (ctrl!= null)
        {
            ctrl.Background = new SolidColorBrush(DefaultSelectedBackground);

        }           
    }

任何想法都会非常受欢迎

4

3 回答 3

3

尽量保持ItemContainerStyle简单。如果你需要弄乱Template项目的,使用ItemTemplateRelativeSource绑定来实现你所需要的。

为了满足您对RelativeSource绑定的要求,我只需要以下ItemContainerStyle内容:

<ListBox.ItemContainerStyle>
  <Style TargetType="{x:Type ListBoxItem}">
    <Setter Property="Background"
            Value="BurlyWood" />
    <Setter Property="HorizontalContentAlignment"
            Value="Stretch" />
    <Setter Property="VerticalContentAlignment"
            Value="Stretch" />
    <Style.Triggers>
      <Trigger Property="IsSelected"
                Value="True">
        <Setter Property="Background"
                Value="Tomato" />
      </Trigger>
      <Trigger Property="IsMouseOver"
                Value="True">
        <Setter Property="Background"
                Value="CadetBlue" />
      </Trigger>
    </Style.Triggers>
  </Style>
</ListBox.ItemContainerStyle>

现在为了得到这个BackgroundUserControl我的UserControlxaml 就像:

<UserControl ...
             Background="{Binding RelativeSource={RelativeSource FindAncestor,
                                                                 AncestorType={x:Type ListBoxItem}},
                                  Path=Background}">

就是这样,我们已经排序了。

你可以从这里获得这个演示:这里

更新:

如果您正在UserControl从代码隐藏创建(不知道为什么需要,但无论如何),也可以在代码隐藏中分配绑定。就像是:

public UserControl CreateUserControl(string text) {
  Binding binding = new Binding {
    Path = new PropertyPath(BackgroundProperty),
    RelativeSource = new RelativeSource() {
      Mode = RelativeSourceMode.FindAncestor,
      AncestorType = typeof(ListBoxItem)
    }
  };
  var uc = new UserControl {
    Content = new TextBlock {
      Text = text,
      FontSize = 24,
      FontWeight = FontWeights.Bold,
      HorizontalAlignment = HorizontalAlignment.Center,
      VerticalAlignment = VerticalAlignment.Center
    }
  };

  BindingOperations.SetBinding(uc, BackgroundProperty, binding);
  return uc;
}

并且ItemContainerStyle会和以前一样,你应该完成。

这种方法的演示:这里

于 2013-09-04T08:57:40.950 回答
1

为了实现您所说的,您可以将您的面板包装ContentPresenter在一个面板中(例如Grid)并用于TemplateBinding设置背景。

样本控制模板:

<ControlTemplate TargetType="ListBoxItem">
    <Grid Background="{TemplateBinding Background}">
        <ContentPresenter Content="{Binding}" />
    </Grid>

    <ControlTemplate.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="Fuchsia" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>
于 2013-09-04T09:08:23.310 回答
0

尝试像这样设置样式触发器:

                <Style.Triggers> 
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelectedProperty}" Value="True"> 
                        <Setter Property="Control.Background" Value="Red" /> 
                    </DataTrigger> 
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelectedProperty}" Value="False"> 
                        <Setter Property="Control.Background" Value="Black" /> 
                    </DataTrigger> 
                </Style.Triggers> 

谢谢

于 2013-09-04T07:37:45.100 回答