Richard Lu
Richard Lu

Reputation: 11

WPF button content is empty when shown

I am new to C#/WPF. There is a view with one button defined, when the view is initialized, buttons will display a set of reason codes got from DataContext (viewmodel), once any button is clicked, the code on it will be saved and passed forward for next processing.

Q: The text on buttons are totally empty, but the clicked code can be captured, so where the problem is about binding? Thanks.

XAML:

<Button x:Name="btnReason" Command="{Binding DataContext.SelectCommand, RelativeSource={RelativeSource AncestorType=v:View, Mode=FindAncestor}}" CommandParameter="{Binding}" Width="190" Height="190" >
    <Border Background="Transparent">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <TextBlock x:Name="Reason" Grid.Row="0" Text="{Binding ?????}" TextWrapping="Wrap" />
        </Grid>
    </Border>
</Button>

The code on C#:

public class ReasonsViewModel : ViewModel
{
    private IEnumerable<string> m_Names;
    public IEnumerable<string> Names
    {
        get { return m_Names; }
        set
        {
            if (m_Names != value)
            {
                m_Names = value;
                OnPropertyChanged(() => Names);
            }
        }
    }

    private string m_SelectedName;
    public string SelectedName
    {
        get { return m_SelectedName; }
        set
        {
            if (m_SelectedName != value)
            {
                m_SelectedName = value;
                OnPropertyChanged(() => SelectedName);
            }
        }
    }

    public DelegateCommand SelectCommand { get; private set; }

    public ReasonsViewModel()
    {
        SelectCommand = new DelegateCommand(p => SelectCommandExecute(p));
    }

    private bool m_Processing;

    private void SelectCommandExecute(object item)
    {
        if (m_Processing) return;

        try
        {
            m_Processing = true;

            var name = item as string;
            if (name == null) return;

            SelectedName = name;
        }
        finally
        {
            m_Processing = false;
        }
    }
}

Upvotes: 1

Views: 481

Answers (1)

David Weis
David Weis

Reputation: 36

If I understood your question correctly than your property text in your TextBlock should be bound to SelectedName.

The problem is that your CommandParameter is bound to DataContext. That's what an empty {Binding} statement bounds to. This means your command handler always returns after the null check.

I also suggest that you change your Names proeprty from IEnumerable<string> to ObservableCollection<string>.
ObservableCollection raises events on any additions or removalof items inside and WPF components can bind to these events.

Upvotes: 1

Related Questions