Prosty binding z label - akt drugi

0

Postanowiłem zrobić binding z decimal do Label. Miałem taki przykładowy i działający programik, który wyświetlał obliczoną, zresztą w prosty sposób, kwotę. Czyli w odpowiednim miejscu było:

   mojaLabel.Text = dopieroCoObliczonaKwota.ToString("#,##0.00") + " PLN";

No to zrobię tu binding zamiast podstawiania, pomyślałem. I czegoś się nauczę.
Małomiękki nawet podaje przykład: https://msdn.microsoft.com/en-us/library/system.windows.forms.binding.format(v=vs.110).aspx
Nic tylko zastosować. Spróbowałem i nie działa. Buuu.

No to pomyślałem, żeby zrobić jakiś prosty przykład. Na formę Label (jako wynik) i NumericUpDown (jako źródło). I to działa. I nie widzę, gdzie się poprzednio walnąłem. No to, myślę sobie, przerobię ten działający na ten bardziej złożony. Może mi wyjdzie, kiedy przestanie działać. Co tam, przynajmniej poćwiczę.

Przestało działać niespodziewanie szybko. Zrobiłem tak:
Nowy projekt winforms o nazwie "Binding decimal property to label". Na formę label z nazwą labelQuote. Dalej NumericUpDown z nazwą EndState i zdarzeniem ValueChanged. I robimy taki kod:

using System;
using System.Windows.Forms;

namespace Binding_decimal_property_to_label
{
    public partial class FormWorking : Form
    {
        public FormWorking()
        {
            InitializeComponent();
            var binding = new Binding("Text", this, "LabelValue");
            binding.Format += new ConvertEventHandler(DecimalToCurrencyString);
            labelQuote.DataBindings.Add(binding);
        }

        private decimal prevQuote = 0;

        public decimal LabelValue
        {
            get { return prevQuote; }
            set { if (Equals(prevQuote, value)) return; prevQuote = value; OnLabelValueChanged(); }
        }

        public event EventHandler LabelValueChanged;

        protected virtual void OnLabelValueChanged() { LabelValueChanged?.Invoke(this, EventArgs.Empty); }

        private void DecimalToCurrencyString(object sender, ConvertEventArgs cevent)
        {
            if (cevent.DesiredType != typeof(string)) return;
            cevent.Value = ((decimal)cevent.Value).ToString("#,##0.00") + " PLN";
        }

        private void UpdateQuote() { LabelValue = EndState.Value; }

        private void EndState_ValueChanged(object sender, EventArgs e) { UpdateQuote(); }
    }
}

No i to działa. Nazwę "LabelValue" mamy w trzech miejscach:

            var binding = new Binding("Text", this, "LabelValue");

i

        public decimal LabelValue

oraz

        private void UpdateQuote() { LabelValue = EndState.Value; }

I teraz, zamieniając nazwę "LabelValue" na "PrevQuote", uzyskuję kod:

using System;
using System.Windows.Forms;

namespace Binding_decimal_property_to_label
{
    public partial class FormWorking : Form
    {
        public FormWorking()
        {
            InitializeComponent();
            var binding = new Binding("Text", this, "PrevQuote");
            binding.Format += new ConvertEventHandler(DecimalToCurrencyString);
            labelQuote.DataBindings.Add(binding);
        }

        private decimal prevQuote = 0;

        public decimal PrevQuote
        {
            get { return prevQuote; }
            set { if (Equals(prevQuote, value)) return; prevQuote = value; OnLabelValueChanged(); }
        }
        public event EventHandler LabelValueChanged;

        protected virtual void OnLabelValueChanged() { LabelValueChanged?.Invoke(this, EventArgs.Empty); }

        private void DecimalToCurrencyString(object sender, ConvertEventArgs cevent)
        {
            if (cevent.DesiredType != typeof(string)) return;
            cevent.Value = ((decimal)cevent.Value).ToString("#,##0.00") + " PLN";
        }

        private void UpdateQuote() { PrevQuote = EndState.Value; }

        private void EndState_ValueChanged(object sender, EventArgs e) { UpdateQuote(); }
    }
}

I on nie działa. Co jest?

0

Pewnie należałoby nieco odwrócić pytanie. Dlaczego nazwa "LabelValue" jest "lepsza" od nazwy "PrevQuote"?

0

Dzięki wydatnej pomocy kolegi wiem coś więcej. Otóż poza zmianami, które zrobiłem, należy jeszcze zmienić jedną nazwę. Kod:

        public event EventHandler LabelValueChanged;

        protected virtual void OnLabelValueChanged() { LabelValueChanged?.Invoke(this, EventArgs.Empty); }

podczas wykonania w drugim powyżej wierszu w miejscu LabelValueChanged? mamy wartość null. Ale jeśli i tu zmienimy nazwę z LabelValueChanged na PrevQuoteChanged to zaczyna nam działać. No cóż, dla mnie to paranoja. Jeśli własność nazywa się JakośTam to aby móc związać z nią zdarzenie musimy je nazwać JakośTamChanged.

1 użytkowników online, w tym zalogowanych: 0, gości: 1