1

ボタンをクリックすると、C#で画像ボックスがフェードアウトします。フェードアウト後、同じ画像ボックスが次の画像でフェードインします。現在、フェードアウトコードをフェードアウト条件とフェードイン条件の両方に配置しています。(フェードイン用にコードを書き直す必要があります。)コードが2番目の画像のロジックに到達すると、条件がfalseになり、表示を変更せずに終了するまで、コードはループします。2番目の画像で同じ効果が得られるようにコードを修正するにはどうすればよいですか?また、フェードインのフェードアウトロジックを書き直す方法を知っている人がいたら、私に知らせてください。

上部で定義された変数:

int alpha = 0;
    bool backButtonClick = false;
    bool breakCheck = false;

ボタンのロジックスニペット:

        private void storyChooser_Click(object sender, EventArgs e)
        {

            switch (userChoice)
            {
                case Choice.Son:

                    transitions();


                     if (alpha == 0)
                    {
                        pictureBox1.Image = Properties.Resources.test;
                        timer1.Start();

                    }
                break;
            }

タイマー:

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (backButtonClick == true)
            {
                timer1.Stop();
                alpha = 0;
                backButtonClick = false;
            }

            if (alpha++ < 40)
            {
                Image image = pictureBox1.Image;
                using (Graphics g = Graphics.FromImage(image))
                {
                    Pen pen = new Pen(Color.FromArgb(alpha, 255, 255, 255), image.Width);
                    g.DrawRectangle(pen, -1, -1, image.Width, image.Height);
                    g.Save();

                }
                pictureBox1.Image = image;
            }
            else
            {
                timer1.Stop();
            }

            if (alpha == 40 && breakCheck == false)
            {
                pictureBox1.Image = Properties.Resources.transitionTest;

                timer1.Start();

                while (alpha-- > 0)
                {
                    Image image = pictureBox1.Image;
                    using (Graphics g = Graphics.FromImage(image))
                    {
                        Pen pen = new Pen(Color.FromArgb(alpha, 255, 255, 255), image.Width);
                        g.DrawRectangle(pen, -1, -1, image.Width, image.Height);
                        g.Save();

                    }
                    pictureBox1.Image = image;
                    label1.Text = alpha.ToString();
                }
                breakCheck = true;
            }
            label1.Text = alpha.ToString();
        }

グラフィックを更新せずに、タイマーの下部に向かってwhileループを実行しています。

ありがとう。

4

4 に答える 4

1

2番目のフェードイン条件にwhileループがあるようです。

これにより、次のタイマーティックイベントの前に、コントロールが一方の側からもう一方の側に移動します。

しかし、私はあなたのコードを書き直さなければならなかったので、私はそれをより良く感じることができました。

画面に直接書き込むために使用しているのに、なぜPictureBoxコントロールを使用しているのですか?Graphic

これがあなたのコードの私の恐ろしいマングリングです。気分を害しないことを願っています。

VSが悪い定義について文句を言わないように、私はすべての変数を前もって宣言しました。

私も画像を持っていなかったtransitionTestので、これを定義しProperties_Resources_transitionTestました。

int MAX = 40;
int alpha;
bool backButtonClick;
bool breakCheck;
Label label1;
Image Properties_Resources_transitionTest;
Image image;

以下のものを初期化し、開始しました。transition()あなたの列挙型が何を意味するのか、またはそのメソッドがあなたが呼び出したもののためのものだったのかわかりません。

private void storyChooser_Click(object sender, EventArgs e) {
  alpha = 0;
  backButtonClick = false;
  breakCheck = false;
  image = Properties_Resources_transitionTest;
  timer1.Start();
}

backButtonClickとの値についてはbreakCheck、次のようにフォームのクリックイベントハンドラー内に配置します。

private void backButton_Click(object sender, EventArgs e) {
  backButtonClick = !backButtonClick;
}

private void break_Click(object sender, EventArgs e) {
  breakCheck = true;
  // easier to just write
  // timer1.Stop();
}

このTimerTickイベントハンドラーは、あなたがやろうとしていることを処理する必要があります。whileループも削除されていることに注意してください。

private void timer1_Tick(object sender, EventArgs e) {
  if (!breakCheck) {
    using (Pen p = new Pen(Color.FromArgb(alpha, 255, 255, 255), image.Width)) {
      using (Graphics g = Graphics.FromImage(image)) {
        g.DrawRectangle(p, 0, 0, image.Width, image.Height);
      }
    }
    if (backButtonClick) {
      alpha--;
      if (alpha == 0) {
        timer1.Stop();
      }
    } else {
      alpha++;
      if (alpha == MAX) {
        timer1.Stop();
      }
    }
  } else {
    timer1.Stop();
  }
  label1.Text = alpha.ToString();
}

更新:コメントの質問ごと:

backButtonClicktrueの場合alpha、タイマーがティックするたびに値が1ずつ減少し、alphaゼロになると停止します。

backButtonClickfalseの場合、alphaに達するまで増加しMAX、タイマーを停止します。

alpha色の不透明度を制御するため、設定しPenた値に応じて、画像がフェードインおよびフェードアウトして表示backButtonClickされます。

それがあなたが求めていることだと思いますが、私は間違っている可能性があります。

于 2013-02-05T22:53:44.503 に答える
1

これは、これをすべてwhileループで実行しているためである可能性があります。変更する前に、UIが自分自身を再描画する機会がありません。

減算部分は、一度に行うのではなく、タイマーティック内でも実行することをお勧めします。

于 2013-02-05T22:01:16.027 に答える
0

次の部分をスキップするという意味だと思います。

 if (alpha == 40 && breakCheck == false)

次の行のために、アルファの増分を39の値で停止したため、これは実行されないと思います。

if (alpha++ < 40)

等しくない値に変更すると、次のように実行されます。

if (alpha++ <= 40)
于 2013-02-05T21:53:04.800 に答える
-1

なぜ人々はwinformsをそんなに強く主張するのですか?

ほら、これはWPFで20行のXAMLを使用し、C#コードをまったく使用せずに実行できます。

<Window x:Class="WpfApplication4.Window4"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window4" Height="300" Width="300">
    <Window.Resources>
        <Storyboard x:Key="FadeIn" TargetName="Red" Duration="00:00:05">
            <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1"/>
        </Storyboard>
        <Storyboard x:Key="FadeOut" TargetName="Blue" Duration="00:00:05">
            <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0"/>
        </Storyboard>
    </Window.Resources>
    <DockPanel>
        <Button DockPanel.Dock="Top"  HorizontalAlignment="Center" Content="Fade">
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <EventTrigger.Actions>
                        <BeginStoryboard Storyboard="{StaticResource FadeIn}"/>
                        <BeginStoryboard Storyboard="{StaticResource FadeOut}"/>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Button.Triggers>
        </Button>
        <Grid Margin="30">
            <Grid Background="Red" Opacity="0" x:Name="Red"/>
            <Grid Background="Blue" x:Name="Blue"/>
        </Grid>
    </DockPanel>
</Window>

コードビハインド:

using System.Windows;

namespace WpfApplication4
{
    public partial class Window4 : Window
    {
        public Window4()
        {
            InitializeComponent();
        }
    }
}

コードをコピーしてファイル->新しいプロジェクト->WPFアプリケーションに貼り付けるだけで、結果を自分で確認できます。

これらは、背景が単色のグリッドです。<Grid/>sを<Image/>sまたは任意のものに置き換えることができます。

于 2013-02-05T22:03:36.373 に答える