根据值更改高度

时间:2017-02-28 14:12:47

标签: c# wpf

我想创建一个容器,根据增加的参数填充内部颜色。

例如我创建了以下示例: 主窗口:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Border BorderBrush="Black" BorderThickness="1" Width="100" Height="200">
        <Rectangle VerticalAlignment="Bottom" Height="{Binding Height}"  Width="100" Fill="Red" MaxHeight="200"/>
    </Border>
</Grid>

Engine.cs:

class Engine
{
    public ViewModel viewModel = new ViewModel();

    public void process()
    {
        Thread a = new Thread(() =>
        {
            while (viewModel.Height < 200)
            {
                ChangeHeight();
                Thread.Sleep(1000);
            }
        });
        a.IsBackground = true;
        a.Start();

    }
    public void ChangeHeight()
    {
        viewModel.Height++;            
    }
}

ViewModel是datacontext。它运作得很好,但我认为有比我做得更好的东西。 此外,我需要将ChangeHeight()之间的传输更加平滑,这意味着需要动画。

有没有好的例子或指导?

更新 我添加了视图模型代码:

namespace WpfApplication1

{     公共类ViewModel:INotifyPropertyChanged     {        private int m_height = 0;        public int Height         {             得到{return m_height; }             组             {                 m_height = value;                 NotifyPropertyChanged(&#34;身高&#34);             }         }

    #region "PropertyChanged Event"
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}

}

2 个答案:

答案 0 :(得分:1)

您可以在视图中具有附加属性,而不是以编程方式设置视图模型属性的动画,该属性可以为目标属性设置动画,例如: Height

public static class Animated
{
    private static Duration duration = TimeSpan.FromSeconds(5);

    public static readonly DependencyProperty HeightProperty =
        DependencyProperty.RegisterAttached(
            "Height", typeof(double), typeof(Animated),
            new PropertyMetadata(HeightPropertyChanged));

    public static double GetHeight(DependencyObject obj)
    {
        return (double)obj.GetValue(HeightProperty);
    }

    public static void SetHeight(DependencyObject obj, double value)
    {
        obj.SetValue(HeightProperty, value);
    }

    private static void HeightPropertyChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var element = obj as FrameworkElement;

        if (element != null)
        {
            var to = (double)e.NewValue;
            var animation = double.IsNaN(element.Height)
                ? new DoubleAnimation(0, to, duration)
                : new DoubleAnimation(to, duration);

            element.BeginAnimation(FrameworkElement.HeightProperty, animation);
        }
    }
}

您可以在XAML中使用它,如下所示:

<Rectangle Fill="Red" Width="100" Height="0"
    local:Animated.Height="{Binding TargetHeight}"/>

并将TargetHeight视图模型属性设置为所需的目标值。

答案 1 :(得分:0)

使用纯动画

 <Border BorderBrush="Black" BorderThickness="1" Width="100" >
        <Rectangle VerticalAlignment="Bottom" Height="50" Width="100" Fill="Red" >
            <Rectangle.Triggers>
                <EventTrigger RoutedEvent="Loaded">
                    <BeginStoryboard>
                        <Storyboard Storyboard.TargetProperty="Height">
                            <DoubleAnimation From="0" To="{Binding Height}" Duration="0:0:20"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Rectangle.Triggers>
        </Rectangle>
    </Border>

重构您当前的方法,使用Taskasync/await这是编写多线程程序的现代方法。

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        Task.Factory.StartNew(() => { App.Current.Dispatcher.Invoke(async () => 
            {
                while (this.Height < 200)
                {
                    await Task.Delay(1000);
                    ++viewModel.Height;
                }
            }); 
        });
    }