Golang Walk에서 코드에서 RadioButon의 선택 변경

7679 단어 Go
Golang Walk에서는 코드에서 라디오 버튼을 변경하는 방법을 시도했습니다.
package main

import (
    "fmt"
)

import (
    "github.com/lxn/walk"
    . "github.com/lxn/walk/declarative"
)

type Foo struct {
    Bar string
    Baz int
}

func main() {
    foo := &Foo{"b", 0}
    var db *walk.DataBinder
    var rbBar [3]*walk.RadioButton
    var rbBaz [3]*walk.RadioButton

    MainWindow{
        Title:   "Walk RadioButton Example",
        MinSize: Size{320, 240},
        Layout:  VBox{},
        DataBinder: DataBinder{
            AssignTo: &db,
            DataSource: foo,
            AutoSubmit: true,
            OnSubmitted: func() {
                fmt.Println(foo)
            },
        },
        Children: []Widget{
            // RadioButtonGroup is needed for data binding only.
            RadioButtonGroup{
                DataMember: "Bar",
                Buttons: []RadioButton{
                    RadioButton{
                        AssignTo: &rbBar[0],
                        Name:  "aRB",
                        Text:  "A",
                        Value: "a",
                    },
                    RadioButton{
                        AssignTo: &rbBar[1],
                        Name:  "bRB",
                        Text:  "B",
                        Value: "b",
                    },
                    RadioButton{
                        AssignTo: &rbBar[2],
                        Name:  "cRB",
                        Text:  "C",
                        Value: "c",
                    },
                },
            },
            Label{
                Text:    "A",
                Enabled: Bind("aRB.Checked"),
            },
            Label{
                Text:    "B",
                Enabled: Bind("bRB.Checked"),
            },
            Label{
                Text:    "C",
                Enabled: Bind("cRB.Checked"),
            },
            RadioButtonGroup{
                DataMember: "Baz",
                Buttons: []RadioButton{
                    RadioButton{
                        AssignTo: &rbBaz[0],
                        Name:  "oneRB",
                        Text:  "1",
                        Value: 1,
                    },
                    RadioButton{
                        AssignTo: &rbBaz[1],
                        Name:  "twoRB",
                        Text:  "2",
                        Value: 2,
                    },
                    RadioButton{
                        AssignTo: &rbBaz[2],
                        Name:  "threeRB",
                        Text:  "3",
                        Value: 3,
                    },
                },
            },
            Label{
                Text:    "1",
                Enabled: Bind("oneRB.Checked"),
            },
            Label{
                Text:    "2",
                Enabled: Bind("twoRB.Checked"),
            },
            Label{
                Text:    "3",
                Enabled: Bind("threeRB.Checked"),
            },
            PushButton{
                Text: "Apply from Code",
                OnClicked: func() {
                    // ここに実装する
                },
            },
        },
    }.Run()
}
초기 화면은 여기 있습니다.

Applyfrom Code 버튼을 클릭하면 foo가 표시됩니다.Bar를 "c", foo라고 부른다.Baz를 3으로 설정하고 라디오 버튼의 선택을 변경합니다.

우선foo에 값을 설정합니다.
        PushButton{
            Text: "Apply from Code",
            OnClicked: func() {
                foo.Bar = "c"
                foo.Baz = 3
            },
        },
이렇게 되면 라디오 버튼에도 반영이 된다면 할 말은 없지만 반영이 안 된다.
스스로 라디오 버튼의 선택 상태를 업데이트합니다.
1. RadioButton.체크하는 방법 설정
        PushButton{
            Text: "Apply from Code",
            OnClicked: func() {
                foo.Bar = "c"
                foo.Baz = 3

                cbBar := rbBar[0].Group().CheckedButton()
                if cbBar != nil {
                    cbBar.SetChecked(false)
                }
                for _, rb := range rbBar {
                    if rb.Value() == foo.Bar {
                        rb.SetChecked(true)
                        break
                    }
                }

                cbBaz := rbBaz[0].Group().CheckedButton()
                if cbBaz != nil {
                    cbBaz.SetChecked(false)
                }
                for _, rb := range rbBaz {
                    if rb.Value() == foo.Baz {
                        rb.SetChecked(true)
                        break
                    }
                }
            },
        },
RadioButton의 SetChecked를 사용했습니다.언뜻 보기에는 순조로운 것 같지만 rb.Group().CheckButton () 이 SetChecked 후 rb에서 바뀌지 않았기 때문에 실행 후 이상한 현상이 발생할 수 있습니다. (검사를 취소해야 할 단추가 다시 선택 상태로 들어갑니다)
2. RadioButton의 CheckedValue 속성을 사용하는 방법
소스 코드를 보면서 rb를 잘 보세요.Group().RadioButton에는 CheckButton()을 덮어쓸 수 있는 속성이 있습니다.
CheckedValue의 속성입니다.
   rb.MustRegisterProperty("CheckedValue", NewProperty(
        func() interface{} {
            if rb.Checked() {
                return rb.value
            }

            return nil
        },
        func(v interface{}) error {
            checked := v == rb.value
            if checked {
                rb.group.checkedButton = rb
            }
            rb.SetChecked(checked)

            return nil
        },
        rb.CheckedChanged()))
이걸 사용하면 기대한 대로 움직일 거예요.
        PushButton{
            Text: "Apply from Code",
            OnClicked: func() {
                foo.Bar = "c"
                foo.Baz = 3
                cbBar := rbBar[0].Group().CheckedButton()
                if cbBar != nil {
                    prop := cbBar.AsWindowBase().Property("CheckedValue")
                    prop.Set(foo.Bar)
                }
                for _, rb := range rbBar {
                    if rb.Value() == foo.Bar {
                        prop := rb.AsWindowBase().Property("CheckedValue")
                        prop.Set(foo.Bar)
                        break
                    }
                }

                cbBaz := rbBaz[0].Group().CheckedButton()
                if cbBaz != nil {
                    prop := cbBaz.AsWindowBase().Property("CheckedValue")
                    prop.Set(foo.Baz)
                }
                for _, rb := range rbBaz {
                    if rb.Value() == foo.Baz {
                        prop := rb.AsWindowBase().Property("CheckedValue")
                        prop.Set(foo.Baz)
                        break
                    }
                }
3. DataBinder.Reset() 사용 방법
DataBinder를 사용했기 때문에 DataSource를 UI에 반영하는 방법이 있을 것 같아서 소스 코드를 봤더니 DataBinder가 Reset()이라는 방법이 있었다.
실현은 다음과 같다.
        PushButton{
            Text: "Apply from Code",
            OnClicked: func() {
                foo.Bar = "c"
                foo.Baz = 3

                db.Reset()
            },
        },
이것도 기대했던 동작과 같다.이것은 아마 정답일 것이다.

좋은 웹페이지 즐겨찾기