Изменить внешний вид пользовательского элемента управления в зависимости от состояния - PullRequest
0 голосов
/ 17 марта 2011

У меня есть пользовательский элемент управления, который состоит из четырех перекрывающихся элементов: 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 и программировании в целом, и я застрял на том, куда идти дальше. Любые рекомендации будут с благодарностью !!

Ответы [ 2 ]

1 голос
/ 17 марта 2011

Простой способ - использовать преобразователь значений. По сути, это класс, который позволяет вам связывать значение в вашем BusinessObject, и в зависимости от того, что это значение, вы возвращаете другую кисть.

Здесь - пример, показывающий, как именно это сделать.

[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} />

Посмотрите приведенную выше ссылку, чтобы увидеть полный пример.

Преимущество этого способа перед ответом Рэйчел в том, что это общая реализация, поэтому вам не нужно создавать шаблон для каждой из ваших фигур, если вы хотите, чтобы это применялось к различным объектам (прямоугольник, эллипс и т. Д. ...). Но ответ Рэйчел - то есть использование шаблона, тоже хорош, потому что он не требует никакого кода.

0 голосов
/ 17 марта 2011

Вы бы создали триггер на основе свойства 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, который вы должны определить в теге <UserControl>. Что-то вроде <UserControl xmlns:localNamespace="clr-namespace:MyNamespace.MyClassWithStateEnum;assembly=MyNamespace"

...