【问题标题】:Change user control appearance based on state根据状态更改用户控件外观
【发布时间】:2011-07-17 12:14:30
【问题描述】:

我有一个包含四个重叠项的用户控件:2 个矩形、一个椭圆和一个标签

<UserControl x:Class="UserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="50.1" Height="45.424" Background="Transparent" FontSize="24">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="3.303*" />
        <RowDefinition Height="40*" />
        <RowDefinition Height="2.121*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5.344*" />
        <ColumnDefinition Width="40.075*" />
        <ColumnDefinition Width="4.663*" />
    </Grid.ColumnDefinitions>
    <Rectangle Name="Rectangle1" RadiusX="5" RadiusY="5" Fill="DarkGray" Grid.ColumnSpan="3" Grid.RowSpan="3" />
    <Ellipse Name="ellipse1" Fill="{Binding State}" Margin="0.016,0.001,4.663,0" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Stroke="Black" IsEnabled="True" Panel.ZIndex="2" />
    <Label Name="lblNumber" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="White" FontWeight="Bold" FontSize="24" Grid.Column="1" Grid.Row="1" Padding="0" Panel.ZIndex="3">9</Label>
    <Rectangle Grid.Column="1" Grid.Row="1" Margin="0.091,0,4.663,0" Fill="Blue" Name="rectangle2" Stroke="Black" Grid.ColumnSpan="2" Panel.ZIndex="1" />
</Grid>

这是我想要控制用户控件状态的业务对象:

Imports System.Data
Imports System.ComponentModel

Public Class BusinessObject
    Implements INotifyPropertyChanged
    Public logger As log4net.ILog

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Private _state As States
    Public Enum States
        State1
        State2
        State3
    End Enum

    Public Property State() As States
        Get
            Return _state
        End Get
        Set(ByVal value As States)
            If (value <> _state) Then
                _state = value
                RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("State"))
            End If

        End Set
    End Property

    Protected Sub OnPropertyChanged(ByVal name As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
    End Sub

我希望能够在后面的代码中更改业务对象的状态,并在我的用户控件中更改多个形状的颜色。我不确定如何进行绑定。我在后面的代码中设置了用户控件的数据上下文,但不确定这是否正确。我是 WPF 和一般编程的新手,我不知道从哪里开始。任何建议将不胜感激!

【问题讨论】:

    标签: wpf data-binding user-controls wpf-controls


    【解决方案1】:

    一种简单的方法是使用值转换器。基本上,这是一个允许您绑定 BusinessObject 中的值的类,并且根据值是什么,您返回不同的画笔。

    Here 是一个向您展示具体操作方法的示例。

    [ValueConversion(typeof(States), typeof(Brush))]
    public class ColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, 
          object parameter, CultureInfo culture)
      {
         /* return a different brush depending on the state */
      }
    }
    

    然后你像这样绑定它:

    <Ellipse Fill="{Binding State,  Converter={StaticResource colorConverter} />
    

    查看我在上面提供的链接以查看完整示例。

    与 Rachel 的回答相比,这种方式的优势在于它是一个通用实现,因此如果您希望将其应用于不同的对象(矩形、椭圆等),则不必为每个形状创建模板...)。但是 Rachel 的回答——即使用模板也很好,因为它不需要任何代码。

    【讨论】:

      【解决方案2】:

      您将根据 State 属性创建触发器,如果​​它等于 StateX,您将更改颜色。例如:

      <Rectangle>
          <Rectangle.Style>
              <Style TargetType="{x:Type Rectangle}">
                  <Style.Triggers>
                      <DataTrigger Binding="{Binding State} "
                                   Value="{x:Static localNamespace:States.State1}">
                          <Setter Property="Fill" Value="Red" />
                      </DataTrigger>
                  </Style.Triggers>
              </Style>
          </Rectangle.Style>
      </Rectangle>
      

      localNamespace 您必须在 &lt;UserControl&gt; 标记中定义自己。类似&lt;UserControl xmlns:localNamespace="clr-namespace:MyNamespace.MyClassWithStateEnum;assembly=MyNamespace"

      【讨论】:

      • 感谢您的回复。我喜欢这种方法。但是我在声明本地命名空间时遇到问题。我的解决方案名为“Application1”。所以我将本地命名空间声明为 xmlns:localNamespace="clr-namespace:Application1"。它不允许我将其声明为 xmlns:localNamespace="clr-namespace:Application1.BusinessObject" 它说它不包含在程序集中
      • @John 没关系,只需将您的 x:Static 更改为 localNamespace:BusinessObject.States.State1
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-02
      • 2021-01-30
      • 2019-09-26
      相关资源
      最近更新 更多