アプリ版:「スタンプのみでお礼する」機能のリリースについて

ワークテキストボックスにtextBox1とtextBox2を配置し
textBox3に
textBox3.Text=textBox1.Text + textBox2.Text;
とした場合
textBox1とtextBox2のvisibleプロパティをtrueにしている場合は反映されるが
falseにすると反映されません。
AccessBVA等では経験したことがありませんが、VS2017C#でそのようなことが
あるのでしょうか。回避策はありますか。
よろしくお願いします。

質問者からの補足コメント

  • いろいろ調べましたが解決できないので
    内部に変数として持たせ、連結したものをTextBoxに表示させることにしました。

      補足日時:2018/04/09 08:47
  • うーん・・・

    kmeeさんの回答をうけて、再度試してみました。質問時のtextBox1と2はデータバインドしたテキストボックスです。
    再度試したのは、非バインドのテキストボックスにデータが入るようにしたら
    visibleプロパティに関係なく動作しました。
    バインドしたテキストボックスではダメということでしょうか。

      補足日時:2018/04/09 22:12
  • うーん・・・

    別の場所に補足を記入してしまいました。
    kmeeさんの回答をうけて、再度試してみました。質問時のtextBox1と2はデータバインドしたテキストボックスです。
    再度試したのは、非バインドのテキストボックスにデータが入るようにしたら
    visibleプロパティに関係なく動作しました。
    バインドしたテキストボックスではダメということでしょうか。

    No.1の回答に寄せられた補足コメントです。 補足日時:2018/04/10 21:32
  • visible=true; で実行、各テキストボックスにデータが入っていることを確認。
    visible=false; で実行し、MessageBoxで各テキストボックスの値を確認すると何も入っていない。
    従って、連結用のテキストボックスにも何も入らない。
    このような状況です。
    よろしくお願いします。

    No.2の回答に寄せられた補足コメントです。 補足日時:2018/04/11 00:03
  • マイクロソフトのサイトにそれらしき記載がありましたので試してみました。
    visibleプロパティをいつ設定したかによって挙動が異なるようです。
    デザイナーでfalseに設定した場合はハンドルされない。
    従って、フォームをロード後に、コードでfalseに設定するとよい。
    そのように修正したら、期待通りの動きとなりました。
    すべて納得できたわけではありませんが、引き続き調べてみます。

    No.3の回答に寄せられた補足コメントです。 補足日時:2018/04/11 15:53
  • いろいろありがとうございます。
    ご参考にしてください。
    https://social.msdn.microsoft.com/Forums/vstudio …

    No.4の回答に寄せられた補足コメントです。 補足日時:2018/04/11 23:29

A 回答 (5件)

なるほど、確かに再現しました。

初めて知りました。

class BindValue
{
public string Text1 { get; set; } = "hoge";
public string Text2 { get; set; } = "fuga";
public string Text3 { get; set; }
}

textBox1, textBox2, textBox3ともに、BindValueの各値にバインド。

public partial class Form1 : Form
{
private BindValue bindValue = new BindValue();

public Form1()
{
InitializeComponent();

bindValueBindingSource.DataSource = bindValue;

// コンストラクタまたはデザイナでfalseにすると、バインドは表示されるまで無効
//textBox1.Visible = false;
//textBox2.Visible = false;
}

protected override void OnCreateControl()
{
base.OnCreateControl();
// ここでfalseにすればバインドは動く
//textBox1.Visible = false;
//textBox2.Visible = false;
}

private void Form1_Load(object sender, EventArgs e)
{
// ここでfalseにすればバインドは動く
//textBox1.Visible = false;
//textBox2.Visible = false;
}

private void button1_Click(object sender, EventArgs e)
{
textBox1.Visible = !textBox1.Visible;
textBox2.Visible = !textBox2.Visible;
}

private void button2_Click(object sender, EventArgs e)
{
//textBox3.Text = textBox1.Text + textBox2.Text;
var bindValue = bindValueBindingSource.DataSource as BindValue;
textBox3.Text = bindValue.Text1 + bindValue.Text2;
}

private void button3_Click(object sender, EventArgs e)
{
textBox1.Text = "test";
}
}

コンストラクタやデザイン上でVisible = False は、そもそも画面描画する必要ないでしょってことから、
OnCreateControl()で描画対象にならないので、バインドも自然とされないということのようですね。

ともすれば、InitializeComponentState()などのメソッドを用意してあげて、
OnCreateControl()またはLoadイベントで呼び出し、表示の初期値を変化させる、
という方法が最適そうですね。

場合によってコントロールの表示/非表示を切り替えるような動作をするならば、
どうせロジック内で切り替えているわけですから、そこまで苦になる実装ではないかと思います。
(むしろコード基準で、初期値は非表示かと認識できるので、悪くもない)

常に非表示のコントロールだとしたらデザイン上はWidth=0にするか、やはり上記コードで
Visible = falseにするかのどちらかですね。
(Width=0は視覚的に認識できないのでおすすめしませんが)

先に述べた理由で、バインドされていない値がTextBoxの値に設定されている場合があります。
textBox1.Text = "test"
bindValue.Text1 = "hoge"
の状態。
この状態があり得る実装を行っていると、意図しない値が制御される恐れもあります。
そのため、やはり内部で変数で持ち回る、という方法は避けた方がいいでしょう。
(さらに、持ち回る実装をするならバインドしている意味があまりない)
    • good
    • 0
この回答へのお礼

ありがとうございました。
小生も経験したことがない挙動だったので、悩んでしまいました。
naktakさんの仰る通り、内部の変数を持回るのはやめたほうがよいですね。

お礼日時:2018/04/12 21:44

ちょっとよく分かりませんが、WinFormsを前提として試しています。



デザイナでデータバインドしている場合、デザイナでTextプロパティに値を設定しても、
以下のようなコードでは値は取得できません。
これはデータバインドを実施した瞬間、デザイナで指定しているText値は無効になるからです。
var bindValue = bindValueBindingSource.DataSource as BindValue;
textBox3.Text = bindValue.Text1 + bindValue.Text2;

上記を求めるならば、TextBoxのTextプロパティではなく、バインドしているオブジェクトの
初期値を設定すべきです。

上記はVisibleとは関係のない話ですが・・・。

具体的なコードはどうされているのですか?
それと後学のために、記載があったMicrosoftのページをご提示いただけると助かります。
この回答への補足あり
    • good
    • 0

class BindValue


{
public string Text1 { get; set; }
public string Text2 { get; set; }
public string Text3 { get; set; }
}

textBox1, textBox2, textBox3ともに、BindValueの各値にバインド。

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
textBox1.Visible = !textBox1.Visible;
textBox2.Visible = !textBox2.Visible;
}

private void button2_Click(object sender, EventArgs e)
{
textBox3.Text = textBox1.Text + textBox2.Text;
}
}

単純な実装の、これでは再現しません。

データバインドのオブジェクトを直接操作する形を取っても再現しません。
public partial class Form1 : Form
{
private BindValue bindValue = new BindValue();

public Form1()
{
InitializeComponent();

bindValueBindingSource.DataSource = bindValue;
}

private void button1_Click(object sender, EventArgs e)
{
textBox1.Visible = !textBox1.Visible;
textBox2.Visible = !textBox2.Visible;
}

private void button2_Click(object sender, EventArgs e)
{
var bindValue = bindValueBindingSource.DataSource as BindValue;
textBox3.Text = bindValue.Text1 + bindValue.Text2;
}
}

よって、何らかしらが邪魔して値が消されていたりするのでは。
デバッグでタイミングごとにテキスト値を確認してみてはいかがでしょう。

ムリヤリ変数に入れて云々は、根本的な解決ではないのでバグの温床になりうるでしょう。
この回答への補足あり
    • good
    • 0

反映されませんというのは、どのように反映されないのでしょう?


もともとtestという文字が設定されていたら、その文字が消えるのか、無反応なのか。
視覚的には変化しているが、バインド値を取得すると変わってないとか。
この回答への補足あり
    • good
    • 0

似たようなのは何度もやってますけど、VisibleによってTextの内容が変わるようなことはなかったですよ。



textBox3.Text=textBox1.Text + textBox2.Text

このコード、どこに書いてありますか?

例えば、 textBox1.Leaveイベントのハンドラに書いてあったら、textBox1.Visible=Falseのときは
textBox1のフォーカスが当らない
→フォーカスがあたらなければ、Leaveすることもない
→Leaveイベントは発生しないから実行されない
ということになりますし、

textBox1.TextChamgedイベントのハンドラに書いてあって、
textBox1.text="A";
textBox2.text="B";
でTextChagedイベントでtextBox3を書き換えたあとで
textBox3.text="";
等と上書きしてしまっているとかもありそうです。
この回答への補足あり
    • good
    • 0
この回答へのお礼

ありがとうございます。お世話になります。
buttonのクリックイベントに書いているのですが
textBox1.Text とtextBox2.Textにはテーブルの検索結果として2つの列のデータが
入ります。
textBox3.Textに連結したものを表示させたいのですが質問のようなことになります。

お礼日時:2018/04/09 21:45

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A