1

I'm trying to make some CustomControl Textboxes with validation features. (for example a number only textbox or a zip-code textbox etc.) It should realized in a .dll library file.

My project contains a CustomControl for the textbox, a class wich handles the validations, and a ErrMsgGui CustomControl that should show a error message in a TextBlock (exmp.: Only numbers allowed...)

My problem is that I don't get the TextBlock Text updated when a method in the validation class is called

Is there a way to trigger the PropertyChangeEvent which updates the Textblock text within the validaiton class?

(Im quite new to wpf)

Generic.xaml:

<Style TargetType="{x:Type local:NumTb}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:NumTb}">
                    <TextBox Background="{TemplateBinding Background}" Text="{Binding Source={StaticResource NumTbVm}, Path=NumTbText, UpdateSourceTrigger=PropertyChanged}"/> 
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>



<Style TargetType="{x:Type local:ErrMsgGui}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ErrMsgGui}">
                <TextBlock Text="{ Binding  Source={StaticResource val}, Path=ErrMsgGuiText, UpdateSourceTrigger=PropertyChanged}" Background="{TemplateBinding Background}"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Validations.cs:

    private const string ONLY_NUMBERS_REGEX = @"^[0-9]+$";  //Nur Zahlen

    private string _ErrMsgGuiText;
    public string ErrMsgGuiText
    {
        get { return _ErrMsgGuiText; }
        set
        {
            _ErrMsgGuiText = value;
            Debug.Print("QueryText: " + value);
            OnPropertyChanged("ErrMsgGuiText"); 
        }
    }


    public object[] onlyNumbers(string s2c, bool output)
    {
        object[] objRes = new object[2];
        bool result = true;
        string errMsg = ""; 

        Regex regex = new Regex(ONLY_NUMBERS_REGEX);

        if (s2c != null && s2c != "" && !regex.IsMatch(s2c)) 
        {
            result = false;
            errMsg = "Nur Zahlen sind zulässig";
        }

        objRes[0] = result;
        objRes[1] = errMsg;

        if (output == true) 
        { 
           ErrMsgGuiText = errMsg;

        }  
         return objRes;
    }

    public void onlyNumbers(string s2c)
    {
        onlyNumbers(s2c, true);
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    protected void OnPropertyChanged(string prop)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(prop));

        }

    }

NumTbViewModel.cs:

    Validations val = null;

    public NumTbViewModel() 
    {
        val = new Validations(); 
    }

    private string _NumTbText;
    public string NumTbText 
    {
        get { return _NumTbText; }
        set 
        {
            _NumTbText = value;
            this.OnPropertyChanged("NumTbText");
            val.onlyNumbers(_NumTbText);

        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    protected void OnPropertyChanged(string prop)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(prop));

        }

    }
user3597422
  • 93
  • 1
  • 7

1 Answers1

0

It looks like the TextBlock source is looking at a static resource for the Validations class and the Validations called in your NumTbViewModel is NOT the same as the static resource. A solution could be to add a property to NumTbViewModel.cs and point your binding to that property so the Validations class instances will be the same. In NumTbViewModel.cs add:

Validations _val;
    public Validations Val
    {
        get { return _val; }
        set 
        {
            _val = value;
            this.OnPropertyChanged("Val");
        }
    }

Change your source and path in xaml binding on the TextBlock:

<TextBlock Text="{ Binding  Source={StaticResource NumTbVm}, Path=Val.ErrMsgGuiText, UpdateSourceTrigger=PropertyChanged}" Background="{TemplateBinding Background}"/>

Another way: You could also set the Val property of your NumTbViewModel when you define your static resource like so:

<local:Validations x:Key="val" />
<local:NumTbViewModel x:Key="NumTbVm" Val="{StaticResource val}" />

Doing this you can keep the bindings like you originally had.

MisterXero
  • 1,098
  • 2
  • 9
  • 17
  • thanks for your answer, but is there also a way to use the validation class as source and call the same Validaitions as the static resource? In future there should be a couple of textboxes (like streetTb, telTb...) which all should use that Textblock for the error message – user3597422 Mar 19 '15 at 16:00
  • @user3597422 I suppose you could do something like [this](http://stackoverflow.com/questions/2117886/accessing-a-resource-via-codebehind-in-wpf) and set the Validations object in NumTbViewModel from the xaml code behind. – MisterXero Mar 19 '15 at 20:12
  • @user3597422 I had another thought. Check my edit to the answer. I think setting the Validations property when you define the static resource could do what you want as well. – MisterXero Mar 19 '15 at 20:28
  • thanks again, I changed the code now, but the text still not getting updated. I also set a Debug.Print() in to the Val set block and find out that the it never will called. – user3597422 Mar 20 '15 at 09:00
  • @user3597422 It might be something you already made sure of but in my example I am using _val as the variable name and in your code you had just val. Did you make val the backing field for the property? If not are you still calling val instead of _val? You only need one of the variables. – MisterXero Mar 20 '15 at 13:21