4

Currently i have the problem, that my business object overrides ToString for delivering data to some telerik control (RadListBox/RadListBoxItem). The model which overrides ToString implements INotifyPropertyChanged. Is it possible in c# to raise the method ToString to be changed? The initial values get's displayed well, but later changes will be ignored. For example:

public class ViewModel : UI.MVC.ViewModelBase
{
    private string name;

    [JsonProperty]
    public string Name
    {
        get
        {
            return name;
        }

        set
        {
            name = value;
            RaisePropertyChanged("Name");
        }
    }

    public override string ToString()
    {
        return name ?? "--";
    }
}

For example if Name is chagned, ToString should be called to get the new value.

EDIT

The ViewModel from above is embedded in another viewmodel. which is binded to a RadPropertyGrid:

public class FirstViewModel :  : UI.MVC.ViewModelBase
{
    public FirstViewModel()
    {
        SelectedItem = new ViewModel();
    }

    public object SelectedItem
    {
        get;
    }
}

An instance of RistViewModel is the datacontext of the containing window.

XAML

<telerik:RadPropertyGrid NestedPropertiesVisibility="Visible" 
    x:Name="propertyGrid" Grid.Column="1" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsGrouped="True" 
    Item="{Binding SelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />

Thank you very much!

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
BendEg
  • 20,098
  • 17
  • 57
  • 131
  • How are you binding to ToString() in the first place? – kkyr Nov 18 '15 at 10:26
  • You could try `RaisePropertyChanged(null)` which would indictate that all properties on the object have changed. It might prompt Telerik to re-evaluate. – GazTheDestroyer Nov 18 '15 at 10:27
  • @kyriacos_k that is the default behaviour of the most wpf controls, if not `DisplayMemberPath` is set. – BendEg Nov 18 '15 at 10:30
  • Ah I was thinking you were binding directly to `Name` – kkyr Nov 18 '15 at 10:32
  • @GazTheDestroyer passing `null` did not work. But thank you :) – BendEg Nov 18 '15 at 10:32
  • Posting your XAML would probably help – kkyr Nov 18 '15 at 10:33
  • I hove not so much html. I use the telerik `RadPropertyGrid` with nested properties. The "header" property of the controls binds automatically `ToString`. The `RadPropertyGrid` generates it's member on it's own, so you woun't see so much in the xam. But i will add it :) – BendEg Nov 18 '15 at 10:35
  • Try this: add some event to `ViewModel`, add handler to it in `FirstViewModel` where you call `PropertyChanged("SelectedItem");` on `FirstViewModel`. This should work for xaml you provided in question. – EekTheCat Nov 18 '15 at 10:46

1 Answers1

4

Is it possible in c# to raise the method ToString to be changed?

No, it is not possible. You cannot force other code to call ToString() again as a direct consequence of some other event. For that matter, the only reason INotifyPropertyChanged works is that, by convention, code knows to subscribe to that event and call a property getter (which is a type of method) when the event is raised. The event doesn't actually force any code to call the property getter; it's just that anyone who bothered to subscribe to the event is almost certainly going to call that method when the event is raised.

Of course, you can always set up whatever mechanism between consenting pieces of code you want. But for code that itself has no reason to believe that it might get a different result from ToString() depending on when it's called, such a mechanism won't exist.

For example if Name is chagned, ToString should be called to get the new value.

You can always subscribe to INotifyPropertyChanged.PropertyChanged yourself, and then do something to force the ToString() method to be called again. It is not clear from the little code you provided how this might be done; maybe setting SelectedItem to null and then back to the desired object.


All that said, while I'm not familiar with the control you are using (RadPropertyGrid), assuming it follows the normal WPF model, then if it is in fact displaying the SelectedItem object in some way, I would guess that it's doing so in a manner that would be compatible with the use of a DataTemplate for that type. I.e. if you were to declare a DataTemplate for the ViewModel class, you could bind directly to the Name property. For example:

<DataTemplate DataType="l:ViewModel">
    <TextBlock Text="{Binding Name}"/>
</DataTemplate>

…and WPF would automatically update the displayed name if and when it changes.

Your ToString() method provides a default name value of "--". This could be incorporated into the Name property itself if you want, or you could add a new property, e.g. DisplayName that provides that (i.e. if for some reason you need Name to remain null when the property hasn't been set).

Without a good, minimal, complete code example that shows clearly what you're doing, it's impossible to know for sure what the best approach would be. But it would be surprising for a good WPF library to not support normal binding and templating mechanisms, and instead to rely completely on a ToString() override without any mechanism for value update notifications.

Community
  • 1
  • 1
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136