WPF - Цвет привязки данных к простому простому окну или холсту на фоне окна - Нет элементов управления - PullRequest
0 голосов
/ 20 декабря 2010

Мне нужен ответ, чтобы я мог исследовать.Я вхожу в кирпичную стену здесь:

Я хотел бы использовать:

        for (int c = 0; c < 255; c++)
        {

            Color = Color.FromArgb(255, (byte)c, (byte)(255 - c), (byte)c);
            Thread.Sleep(3);
        }

Каждый раз, когда "Цвет" пересчитывается, я хотел бы окно или холст в окнеНЕМЕДЛЕННО изменить цвет ... так что я получаю ВИДЕТЬ крутые изменения цвета.Почему это так сложно?Мне нужно это увидеть, но я бью кирпичную стену.Я скопировал конвертер типов здесь:

[ValueConversion(typeof(Color),typeof(SolidColorBrush))]
public class ColorBrushConverter : IValueConverter
{


    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Color color = (Color)value;
        return new SolidColorBrush(color);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }

}

СПАСИБО ЗА ЛЮБУЮ ПОМОЩЬ!

Ответы [ 2 ]

0 голосов
/ 20 декабря 2010

Простой пример того, как вы можете привязать свойство цвета из кода к фону холста.На что обратить внимание

  • Реализация INotifyPropertyChanged.Фон для Canvas будет обновляться после OnPropertyChanged, который будет выполняться каждый раз при изменении MyColorProperty.
  • Установка DataContext = this;в конструкторе все элементы управления в Window наследуют этот DataContext (если только он не переопределен).

xaml

<Canvas ...>
    <Canvas.Background>
        <SolidColorBrush Color="{Binding MyColorProperty}"/>
    </Canvas.Background>

Код позади

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    // ...

    private Color m_myColorProperty;
    public Color MyColorProperty
    {
        get
        {
            return m_myColorProperty;
        }
        set
        {
            m_myColorProperty = value;
            OnPropertyChanged("MyColorProperty");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private void SwitchBackground()
    {
        if (MyColorProperty == Colors.Red)
        {
            MyColorProperty = Colors.Black;
        }
        else
        {
            MyColorProperty = Colors.Red;
        }
    }
}

Обновление
Для запуска фоновой анимации вы можете использовать BackgroundWorker, подобный этому

private BackgroundWorker m_changeColorBgWorker = null;

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
    m_changeColorBgWorker = new BackgroundWorker();
    m_changeColorBgWorker.DoWork += new DoWorkEventHandler(m_changeColorBgWorker_DoWork);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
    if (m_changeColorBgWorker.IsBusy == false)
    {
        m_changeColorBgWorker.RunWorkerAsync();
    }
}
void m_changeColorBgWorker_DoWork(object sender, DoWorkEventArgs e)
{
    while (true)
    {
        for (int c = 0; c < 254; c++)
        {
            MyColorProperty = Color.FromArgb(255, (byte)c, (byte)(255 - c), (byte)c);
            Thread.Sleep(10); 
        }
    }
}

Вы можете установить MyColorProperty непосредственно в потоке, поскольку изменения, инициируемые INotifyPropertyChanged, автоматически направляются обратнодиспетчер.Однако это не относится к INotifyCollectionChanged, просто чтобы вы знали.

0 голосов
/ 20 декабря 2010

Вы делаете это в потоке пользовательского интерфейса.Если вы блокируете поток пользовательского интерфейса с помощью Thread.Sleep, пользовательский интерфейс также блокируется (и никакие изменения не применяются).

Решение состоит в том, чтобы использовать таймер вместо цикла.Сохраните c в некоторой переменной вашего окна.Установите таймер, который истекает через 3 мс, увеличивает c, изменяет Color, а затем сбрасывает таймер, чтобы он снова отключился через 3 мс.

В качестве альтернативы, вы можете запустить фоновый поток, который циклично (и используетThread.Sleep).В этом случае вы должны применить изменение цвета через Dispatcher.Invoke вместо простой установки Color = ....


Чтобы проиллюстрировать мою точку зрения, вот краткий пример того, как это сделать с фоновым потоком:

// define the background thread
var colorChangeThread = new Thread(new ThreadStart(() => {
    for (int c = 0; c < 255; c++)
    {  
        // this (and only this) is done in the UI thread
        Dispatcher.Invoke(new Action(() => {
            this.Background = new SolidColorBrush(Color.FromArgb(255, (byte)c, (byte)(255 - c), (byte)c)); 
        }));

        Thread.Sleep(8);    // the background thread waits
    }
}));
colorChangeThread.Start();  // start the background thread

Если вы используете свойства с INotifyPropertyChanged, вы можете пропустить Dispatcher.Invoke и просто установить свое свойство, см. Объяснение в ответе Meleaks.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...