質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.77%

WPFでX, Yのtextboxに値が入っているときだけOKbuttonを押せるようにしたいです。

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 7,492

score 52

こんにちは。 
X, Yのtextboxに値が入っているときだけOKbuttonを押せるようにしたいです。
Windows10, VisualStudio2015,C#6.0, Livetの組み合わせで開発しています。  
MVVMモデルです。  

現在のコードです。

TODO
・TextBoxのPropertyChangedを探す、なければ作る。どこにどう作るもの?
・TextBoxのPropertyChangedで、IsOkButtonEnabled の値を変更。

たとえばMVVMでなければ、
<TextBox Text="{Binding XTextBoxText}" x:Name="LocationXTextBox"/>

<TextBox Text="{Binding XTextBoxText}" x:Name="LocationXTextBox" TextChanged="LocationXTextBox_TextChanged"/>
とし、
private void LocationXTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
TextBox textbox = sender as TextBok;
if (!String.IsNullOrEmpty(textbox.Text))                OKbutton.IsEnabled = true;
}
とすればOKと思います。
MVVM(Livet)的な方法をご教示ください。

<TextBox Text="{Binding XTextBoxText}" x:Name="LocationXTextBox"/>
<TextBox Text="{Binding YTextBoxText}" x:Name="LocationYTextBox"/>
<Button Content="OK" IsEnabled="{Binding IsOkButtonEnabled}"/>
using System;
using System.Text;
using System.Windows;

using Livet;
using Livet.Commands;
using Livet.Messaging;

namespace XYWindow
{
    public class CoordinateXYWindowViewModel : ViewModel
    {
        public string XTextBoxText { get; set; }

        public string YTextBoxText { get; set; }

        public bool IsOkButtonEnabled { get; set; }

    }
}

propertyの変更とeventを結びつけるのに、

public string XTextBoxText
{
get;
set
{
RaisePropertyChanged("XTextBoxText");
}
}
としたところ、
abstract, extern または partial に指定されていないため、本体を宣言する必要があります。
となって先に進めずにいます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

蛇足ですが
ReactivePropertyを使うと

public ReactiveProperty<string> XTextBoxText { get; } = new ReactiveProperty<string>();
public ReactiveProperty<string> YTextBoxText { get; } = new ReactiveProperty<string>();
public ReactiveCommand OkButtonCommand { get; }
public MainVM()
{
    OkButtonCommand =
        XTextBoxText
        .CombineLatest(YTextBoxText, (x, y) => !(string.IsNullOrEmpty(x) || string.IsNullOrEmpty(y)))
        .ToReactiveCommand(false);

    OkButtonCommand.Subscribe(_ => SomethingToDo());
}

private void SomethingToDo()
{
    Console.WriteLine("Hello!");
}

のように書けます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

TODO 
・TextBoxのPropertyChangedを探す、なければ作る。どこにどう作るもの? 
・TextBoxのPropertyChangedで、IsOkButtonEnabled の値を変更。

プロパティ変更通知は、(基本的には)ViewModelからViewに対してModelが変更されたことを通知する目的で使用します。
ViewはViewModelの参照を持っていますので、ViewModelに対して変更通知を行う必要はありません。
WPFのMVVMについて、各クラスの関係や役割分担を今一度、整理されることをお勧めします。


実装例の一つとして、ICommandインターフェースを利用する方法があります。
Livetをお使いとのことですので、比較的容易に実装可能です。
Livetでの実装例を以下に示しますが、Livet等のインフラストラクチャを使用せず、
自力で実装する方法も勉強しておきましょう。
(ICommandインターフェースの実装例を示すため、Modelは省略しました)

View

<TextBox Text="{Binding XTextBoxText}" x:Name="LocationXTextBox"/>
<TextBox Text="{Binding YTextBoxText}" x:Name="LocationYTextBox"/>
<Button Content="OK" Command="{Binding OKCommand}"/>

ViewModel

public class XYWindowViewModel : ViewModel
{

    #region XTextBoxText変更通知プロパティ
    private string _XTextBoxText;

    public string XTextBoxText
    {
        get
        { return _XTextBoxText; }
        set
        { 
            if (_XTextBoxText == value)
                return;
            _XTextBoxText = value;
            RaisePropertyChanged();
            OKCommand.RaiseCanExecuteChanged();
        }
    }
    #endregion


    #region YTextBoxText変更通知プロパティ
    private string _YTextBoxText;

    public string YTextBoxText
    {
        get
        { return _YTextBoxText; }
        set
        { 
            if (_YTextBoxText == value)
                return;
            _YTextBoxText = value;
            RaisePropertyChanged();
            OKCommand.RaiseCanExecuteChanged();
        }
    }
    #endregion


    #region OKCommand
    private ViewModelCommand _OKCommand;

    public ViewModelCommand OKCommand
    {
        get
        {
            if (_OKCommand == null)
            {
                _OKCommand = new ViewModelCommand(OK, CanOK);
            }
            return _OKCommand;
        }
    }

    public bool CanOK()
    {
        return !string.IsNullOrEmpty(XTextBoxText) && !string.IsNullOrEmpty(YTextBoxText);
    }

    public void OK()
    {
        // DoSomething
    }
    #endregion



    public void Initialize()
    {
    }
}


余談ですが、Livetのコードスニペットは利用していますか?
変更通知プロパティであれば、lprop(n)
コマンドであれば、lvcom(n)やllcom(n)
と入力し、Tabキーを押すことで、規定のコードを挿入できます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/29 10:22

    ありがとうございます。
    昨日丸1日かかりましたが、自分で書けました。
    setのなかで処理する、というのがわかり、なるほどとひとつ賢くなりました。

    コードスニペットアドバイス感謝します。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る