ページ 11

ゲッター/セッターについて

Posted: 2010年4月26日(月) 15:27
by 山口
言語はVC++2005でXPを使っております。

VC++2005にて親ウインドウの特定のボタンを押すと
子ウインドウを呼び出すという処理を行っております。

子ウインドウが呼び出された時には初期値を親から渡し
子ウインドウが閉じられる時は親ウインドウに値を渡すと言った処理を行おうとしております。
調べてみるとゲッター/セッターの考え方を使うと出来ると書いてありました。

閉じるとき親ウインドウに渡すことは出来たのですが
子ウインドウの初期値を設定することが出来ません。
これでは駄目なのでしょうか?
一部省略にて失礼します。
// 親
    // フォームのセット
    AlarmSet^ Set;
    if(Set)    delete Set;
    Set = gcnew Alarm::AlarmSet();
    Set->ShowDialog(this);
    Set->SetSchedule("aa"); // 初期値
    
    // 値の取得
    String^ day = Set->GetDay();
    String^ time = Set->GetTime();
    String^ Schedule = Set->GetSchedule();

// 子
    // ゲッター
    public: String^ GetDay(){
                return dateTimePickerDay->Text;
    }
    public: String^ GetTime(){
                return dateTimePickerTime->Text;
    }
    public: String^ GetSchedule(){
                return textBoxSchedule->Text;
    }

    // セッター
    public: void SetDay(String^ value){
                dateTimePickerDay->Text = value;
    }
    public: void SetTime(String^ value){
                dateTimePickerTime->Text = value;
    }
    public: void SetSchedule(String^ value){
                textBoxSchedule->Text = value;
    }

Re:ゲッター/セッターについて

Posted: 2010年4月26日(月) 15:58
by YuO
Form::ShowDialogは,そのフォームが閉じられるまで処理を戻しません。
初期値の設定は,ShowDialogよりも前におこなってください。
# この例だと,setter/getterよりproperty使うかなぁ……。
MSDN: Form.ShowDialog メソッド () (System.Windows.Forms)
http://msdn.microsoft.com/ja-jp/library/c7ykbedk(VS.80).aspx

Re:ゲッター/セッターについて

Posted: 2010年4月26日(月) 18:31
by 山口
お蔭様で出来ました!!回答ありがとうございます。
又、バグ?を見つけてしまいました。

子ウインドウで登録ボタンを押したら子ウインドウを閉じて
親ウインドウに値を反映すると言ったことを行っています。
しかし登録ボタンを押さなくてAlt+F4等で閉じた際も値の反映が行われてしまいます。

原因はなんとなくわかるのですが解決法がわかりません。

子ウインドウのボタンを押したときには閉じるだけです。
※多分ここと値の取得方法が問題だと思います。
private: System::Void buttonSet_Click(System::Object^ sender, System::EventArgs^ e) {
this->Close();
}

又、今回のソースでは3つの値をやりとりしcheckedListBoxのアイテムに追加しております。

String^ day = Set->GetDay();
String^ time = Set->GetTime();
String^ Schedule = Set->GetSchedule();
String^ Item = day + " " + time + " " + Schedule;
// アイテムの追加
this->checkedListBox1->Items->Add(Item);

この様にしてしまっている為、リストボックス0番のtimeが
知りたいと言った場合の取得が出来なくなってしまっております。
SubString等で切り出しを行ってみたのですが12月等の桁が多い月にはバグが出てしまいます。
これを改善したいのですがどの様にすればよいのでしょうか・・・。

Re:ゲッター/セッターについて

Posted: 2010年4月27日(火) 00:21
by YuO
> 子ウインドウで登録ボタンを押したら子ウインドウを閉じて
> 親ウインドウに値を反映すると言ったことを行っています。
> しかし登録ボタンを押さなくてAlt+F4等で閉じた際も値の反映が行われてしまいます。

ダイアログボックスの使い方について説明すると長くなりそうなので,まずはMSDNを。
MSDN: Windows フォームのダイアログ ボックス
http://msdn.microsoft.com/ja-jp/library/2chz8edb(v=VS.80).aspx

というわけで,
・登録ボタンのDialogResultプロパティをDialogResult::OKに設定する
・登録ボタンのClickイベントは削除する
・ShowDialogの戻り値がDialogResult::OKかどうかを判定する
というように変更すればよいと思います。


> この様にしてしまっている為、リストボックス0番のtimeが
> 知りたいと言った場合の取得が出来なくなってしまっております。
> SubString等で切り出しを行ってみたのですが12月等の桁が多い月にはバグが出てしまいます。
> これを改善したいのですがどの様にすればよいのでしょうか・・・。

方法はいくつかあると思いますが……。
・day, time, scheduleを持つクラスをひとつ用意し,ToStringをオーバーロードしてday + " " + time + " " + Scheduleを返すようにしておく
→Itemsからオブジェクトを取得できるので,ばらばらのデータが取得可能。
・String::SplitやRegex::Splitで,day, time, scheduleを正確に分割するようにする
→day/time/scheduleにスペースが入らないのであればString::Split,そうでなければRegex::Split
個人的には前者の方が多いですね。
あとあと楽ですし。

Re:ゲッター/セッターについて

Posted: 2010年4月27日(火) 02:12
by 山口
お忙しい中、ご回答ありがとうございます。

> 子ウインドウで登録ボタンを押したら子ウインドウを閉じて
> 親ウインドウに値を反映すると言ったことを行っています。
> しかし登録ボタンを押さなくてAlt+F4等で閉じた際も値の反映が行われてしまいます。
お陰さまでこちらの問題を解決することが出来ました。
ありがとうございます。

・day, time, scheduleを持つクラスをひとつ用意し,ToStringをオーバーロードしてday + " " + time + " " + Scheduleを返すようにしておく
→Itemsからオブジェクトを取得できるので,ばらばらのデータが取得可能。

のやり方で実装しようと思うのですが親ウインドウに
private: String^ Day;
private: String^ Time;
private: String^ Schedule;
private: String^ Item;
を追加するということでしょうか?
イマイチわからないのですがご教授いただけないでしょうか?

Re:ゲッター/セッターについて

Posted: 2010年4月27日(火) 11:49
by YuO
説明するのが面倒なので,コードを書いてしまいます。
以下のクラスを,CheckedListBox::Itemsに追加するようにしてください。
C++/CLIを普段使わないので,コンパイルできることだけのチェックしかしていませんが……。

---- Class1.h
#pragma once

public ref class Class1
{
private:
::System::String^ day_;
::System::String^ time_;
::System::String^ schedule_;

public:
Class1 (::System::String^ day, ::System::String^ time, ::System::String^ schedule);

property ::System::String^ Day { ::System::String^ get(); };
property ::System::String^ Time { ::System::String^ get(); };
property ::System::String^ Schedule { ::System::String^ get(); };

virtual ::System::String^ ToString () override;
};

---- Class1.cpp
#include "stdafx.h"
#include "Class1.h"

Class1::Class1 (::System::String^ day, ::System::String^ time, ::System::String^ schedule) : day_(day), time_(time), schedule_(schedule)
{
}

::System::String^ Class1::Day::get()
{
return day_;
}

::System::String^ Class1::Time::get()
{
return time_;
}

::System::String^ Class1::Schedule::get()
{
return schedule_;
}

::System::String^ Class1::ToString ()
{
return ::System::String::Format(L"{0} {1} {2}", day_, time_, schedule_);
}

Re:ゲッター/セッターについて

Posted: 2010年4月27日(火) 13:01
by 山口
お忙しい中サンプルソースまでありがとうございます。

頂いたソースを追加し

親ウインドウで#include "Class1.h"としました。
>>以下のクラスを,CheckedListBox::Itemsに追加するようにしてください。
これはどういう意味でしょうか?
又、ソースでやっていることはわかるのですが使い方がわかりません・・・。
// 登録ボタン選択時
    private: System::Void buttonSet_Click(System::Object^  sender, System::EventArgs^  e) {
                 
                 // フォームのセット
                 AlarmSet^ Set;
                 if(Set)    delete Set;
                 Set = gcnew Alarm::AlarmSet();
                 
                 if(Set->ShowDialog(this) == System::Windows::Forms::DialogResult::OK){
                     int Num = this->checkedListBox1->Items->Count;
                     // 値の取得
                     String^ day = Set->GetDay(); 
//                     Day[0] = "a";//Set->GetDay();
                     String^ time = Set->GetTime();
                     String^ Schedule = Set->GetSchedule();
                     String^ Item = day + " " + time + " " + Schedule;

                     // アイテムの追加
                     this->checkedListBox1->Items->Add(Item);
                 }
            }
現在ボタンを選択した時は上記の様なソースになっております。
これをどのように改編すればよいのでしょうか・・。

Re:ゲッター/セッターについて

Posted: 2010年4月27日(火) 23:52
by 山口
色々なサイトを見てみたのですがやはり追加するという意味がわかりません・・・。
どうかご回答頂けないでしょうか・・・?

Re:ゲッター/セッターについて

Posted: 2010年4月28日(水) 00:43
by YuO
eratta at [51266]
s/以下のクラス/以下のクラスのインスタンス/


> 色々なサイトを見てみたのですがやはり追加するという意味がわかりません・・・。

具体的に,どこを見たのでしょうか。
また,具体的に何をしましたか。

少なくとも,
MSDN: CheckedListBox.Items プロパティ (System.Windows.Forms)
http://msdn.microsoft.com/ja-jp/library ... tbox.items(v=VS.80).aspx
MSDN: CheckedListBox.ObjectCollection クラス (System.Windows.Forms)
http://msdn.microsoft.com/ja-jp/library ... collection(v=VS.80).aspx
MSDN: ListBox.ObjectCollection.Add メソッド (System.Windows.Forms)
http://msdn.microsoft.com/ja-jp/library ... ection.add(v=VS.80).aspx
のあたりは読んだのですよね。
# 山口さんのコードで使われているプロパティ・クラス・メソッドのリファレンスですが。

Re:ゲッター/セッターについて

Posted: 2010年4月28日(水) 14:11
by 山口
回答ありがとうございます。
URLもありがとうございます。
MSDN: CheckedListBox.Items プロパティ (System.Windows.Forms) 等は閲覧していたのですが
これのどこでクラスを読み込んでいるのでしょうか?

閲覧したのは
http://dobon.net/
等です。

this->checkedListBox1->Items->Add("あああ");
のようにすればitemsの要素に「あああ」という文字列を追加できることは理解しております。

別のページにクラスを作りそれを要素に追加するということを行ったことがないので理解できませんでした。
どうかご教授いただけないでしょうか?

Re:ゲッター/セッターについて

Posted: 2010年4月29日(木) 21:33
by 山口
URLを張って頂いたのですがやはりわかりません・・・。
ご教授いただけないでしょうか?

Re:ゲッター/セッターについて

Posted: 2010年5月01日(土) 06:13
by 山口
すみません・・・。
色々と試してみたのですが上手くいきません。
item等にクラスを追加することをしたことがなかったのでしっくりきません・・・。
// 登録ボタン選択時
    private: System::Void buttonSet_Click(System::Object^  sender, System::EventArgs^  e) {
                 
                 // フォームのセット
                 AlarmSet^ Set;
                 if(Set)    delete Set;
                 Set = gcnew Alarm::AlarmSet();
                 
                 if(Set->ShowDialog(this) == System::Windows::Forms::DialogResult::OK){
                     Class1::Class1^ val = gcnew class1;
                     //val->

                     /*
                     int Num = this->checkedListBox1->Items->Count;
                     // 値の取得
                     String^ day = Set->GetDay(); 
//                     Day[0] = "a";//Set->GetDay();
                     String^ time = Set->GetTime();
                     String^ Schedule = Set->GetSchedule();
                     String^ Item = day + " " + time + " " + Schedule;

                     // アイテムの追加
                     this->checkedListBox1->Items->Add(Item);
                     */
                 }
            }

Re:ゲッター/セッターについて

Posted: 2010年5月02日(日) 21:02
by YuO
ListBox::ObjectCollection::Addの引数はSystem::Object^。
つまり,managedなオブジェクトであればなんでも引数にとります。

なので,
this->checkedListBox1->Items->Add(val);
とすれば,(いかなる型であれ)valがポイントするオブジェクトをListBoxの要素に追加できます。

Re:ゲッター/セッターについて

Posted: 2010年5月04日(火) 09:11
by 山口
何度もご回答ありがとうございます。
本当に助かります。

実行すると
1>~\alarm\Form1.h(250) : error C2065: 'val' : 定義されていない識別子です。
1>~\デスクトップ\alarm\Form1.h(250) : error C2597: 静的でないメンバ 'Class1::day_' への参照が正しくありません。
1>~\デスクトップ\alarm\Form1.h(250) : error C2061: 構文エラー : 識別子 'class1'

というエラーが出てしまいます。
何故なのでしょうか。


仕様概要
・親と子のウインドウがあります。
・親のボタンをクリックすると子ウインドウが開きます。
・子ウインドウには3つのテキストボックスがあり登録を押すと
 親ウインドウ(リストボックス)にそれぞれの値が渡されます。

編集ボタンを押したときに子ウインドウに反映したり保存する時にCSVで吐き出す為に
親ウインドウで3つの値をそれぞれ分割して管理したいです。

Re:ゲッター/セッターについて

Posted: 2010年5月06日(木) 05:20
by 山口
色々試してみたのですがやはり上手くいきません・・・。
VC++はこちらで聞くのはまずいのでしょうか?
まずいのでしたら締めさせて頂きます。

Re:ゲッター/セッターについて

Posted: 2010年5月07日(金) 06:10
by 山口
必要な機能だけのものを作り挑戦してみてはいるのですが
クラスを追加するということが理解できません。

プロジェクトを添付させて頂きます。