Как изменить цвет фона Silverlight DataGridRow? - PullRequest
1 голос
/ 09 февраля 2011

Сетка данных Silverlight привязана к коллекции MyObjects.MyObject имеет логическое поле с именем IsHighlighted.Я хотел бы изменить цвет фона строки, когда это значение истинно.И вернуть его обратно, если оно станет ложным.

Я уже пытался использовать событие Loading_Row (, как описано здесь ), но у меня это не сработало, так каксобытие вызывается только один раз, и все мои объекты имеют булево значение, установленное на ложь в это время (оно становится истинным, когда выбирается другой компонент; это работает, я проверял значения).

У кого-нибудь есть подсказка?Заранее спасибо!

Обновление : я сделал тестовое приложение для иллюстрации, оно воспроизводит мою проблему.

<navigation:Page x:Class="AViews.Tests" 
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  
           mc:Ignorable="d"
           xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           DataContext="{Binding RelativeSource={RelativeSource Self}}"
           d:DesignWidth="640" d:DesignHeight="480"
           Title="Tests Page">
    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <sdk:DataGrid Grid.Row="0" ItemsSource="{Binding AllItems, Mode=TwoWay}" AutoGenerateColumns="False" LoadingRow="DataGrid_LoadingRow">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Binding="{Binding Value1}" Header="Value1" />
                <sdk:DataGridTextColumn Binding="{Binding Value2}" Header="Value2"/>
                <sdk:DataGridCheckBoxColumn Binding="{Binding IsHighlighted}" Header="Is Highlighted" />
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>

        <Button Content="Change !" Grid.Row="1" HorizontalAlignment="Left" Click="Button_Click" />

    </Grid>
</navigation:Page>

public partial class Tests : Page, INotifyPropertyChanged
{
    private SampleConverter bgConverter = new SampleConverter();
    Random r = new Random();

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    private ObservableCollection<Sample> allItemsField = new ObservableCollection<Sample>();
    public ObservableCollection<Sample> AllItems
    {
        get
        {
            return this.allItemsField;
        }

        set
        {
            if (this.allItemsField != value)
            {
                this.allItemsField = value;
                this.OnPropertyChanged("AllItems");
            }
        }
    }

    public Tests()
    {
        InitializeComponent();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        var tmp = Enumerable.Range(0, 100).Select(f => new Sample(f)).ToList();
        foreach (var item in tmp)
        {
            item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
        }

        var coll = new ObservableCollection<Sample>(tmp);

        this.AllItems = coll;
    }

    void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        this.OnPropertyChanged("AllItems");
    }

    private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
    {
        Binding b = new Binding("IsHighlighted")
        {
            Mode = BindingMode.OneWay,
            Converter = this.bgConverter,
            ValidatesOnExceptions = true
        };

        e.Row.SetBinding(DataGridRow.BackgroundProperty, b);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        foreach (var item in this.AllItems)
        {
            item.IsHighlighted = r.Next(1000) % 2 == 0;
        }
    }
}

public class Sample: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    private string value1Field = string.Empty;
    public string Value1
    {
        get
        {
            return this.value1Field;
        }

        set
        {
            if (this.value1Field != value)
            {
                this.value1Field = value;
                this.OnPropertyChanged("Value1");
            }
        }
    }

    private string value2Field = string.Empty;
    public string Value2
    {
        get
        {
            return this.value2Field;
        }

        set
        {
            if (this.value2Field != value)
            {
                this.value2Field = value;
                this.OnPropertyChanged("Value2");
            }
        }
    }

    private bool isHighlightedField = false;
    public bool IsHighlighted
    {
        get
        {
            return this.isHighlightedField;
        }

        set
        {
            if (this.isHighlightedField != value)
            {
                this.isHighlightedField = value;
                this.OnPropertyChanged("IsHighlighted");
            }
        }
    }

    public Sample(int index)
    {
        this.Value1 = string.Format("Value1 #{0}", index);
        this.Value2 = string.Format("Value2 #{0}", index);
    }
}

public class SampleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool val = (bool)value;
        SolidColorBrush ret = val ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Green);
        return ret;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

И результат можно увидеть на этих фотографиях:

Когда я впервые захожу на страницу.Start

Я нажимаю кнопку, которая устанавливает для некоторых (случайных) значений значение true.Как видите, обновляется привязка, а не пользовательский интерфейс.enter image description here

Я использую полосу прокрутки, иду до конца и возвращаюсь, и О!замечательно!Все строки правильно окрашены: - (

enter image description here

1 Ответ

2 голосов
/ 09 ноября 2011

См. Ссылку ниже, которая решает проблему путем изменения шаблона управления DataGridRow который связывает свойство Fill BackgroundRectangle. Вы можете использовать boolConverter для преобразования из IsHighlighted в SolidColorBrush.

Цветовая привязка строки Silverlight DataGrid

...