如何设置ContentPresenter内容背景

时间:2013-09-04 07:32:39

标签: c# wpf triggers contentpresenter

我有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并且它没有传播UserControls背景......

我现在解决它的方式是使用像这样的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);

        }           
    }

任何想法都会受到很大关注

3 个答案:

答案 0 :(得分: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>

现在要在Background中获取此UserControl,我的UserControl xaml就像:

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

就是这样,我们已经分类了。

您可以从Here

获取此演示

<强>更新

如果您是从代码隐藏中创建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将保持不变,你应该完成。

此方法的演示:Here

答案 1 :(得分: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>

答案 2 :(得分: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> 

由于