Homam
Homam

Reputation: 23851

What's the best practice to bind IsEnabled property for a button with selected item in a data grid?

I have a Data Grid and many buttons for commands on the selected item in the data grid.

These buttons will be hidden or disabled based on properties in the selected item in the grid.

For example: if the selected record IsNew, the button Cancel will be disabled.

What's the best practice to implement a situation like this?

I may implement it in the SelectedItemChange manually like the follwoing:

void myGrid_selectedItemChanged(sender, args..)
{
    cancelButton.IsEnabled = SelectedItem.IsNew ; // just an example
}

The problem with this approach is that, when the selected item is removed, this event will not be fired.

Or in XAML, bind a dependency property with the control:

<!--SelectedItemIsNew is a property in the form and binding it with IsEnabled... -->
<Button x:Name="cancelButton" IsEnabled="{Binding SelectedItemIsNew ...}"/>

The problem here, I must assign a value to the property to notify the bound control, or in other words what's the code here to change the value of the property ?

Another option!

Upvotes: 0

Views: 3556

Answers (3)

Kent Boogaart
Kent Boogaart

Reputation: 178700

An MVVM implementation would look something like this...

View model code:

public class ParentViewModel : ViewModel
{
    private readonly ICommand cancelCommand;
    private readonly ICollection<ChildViewModel> children;
    private ChildViewModel selectedChild;

    public ParentViewModel()
    {
        this.cancelCommand = new DelegateCommand(this.OnCancel, this.CanCancel);
        this.children = new ObservableCollection<ChildViewModel>();
    }

    public ICommand CancelCommand
    {
        get { return this.cancelCommand; }
    }

    public ICollection<ChildViewModel> Children
    {
        get { return this.children; }
    }

    public ChildViewModel SelectedChild
    {
        get { return this.selectedChild; }
        set
        {
            if (this.selectedChild != value)
            {
                this.selectedChild = value;
                this.OnPropertyChanged(() => this.SelectedChild);
            }
        }
    }

    private void OnCancel(object parameter)
    {
        // cancel logic here
    }

    private bool CanCancel(object parameter)
    {
        // can only cancel if there's a child selected
        return this.SelectedChild != null;
    }
}

XAML:

<GridView ItemsSource="{Binding Children}" SelectedItem="{Binding SelectedChild}">
    ...
</GridView>

...

<Button Command="{Binding CancelCommand}" Content="Cancel"/>

Upvotes: 1

Singleton
Singleton

Reputation: 3679

hey, i have the same case some time back, i always do that when ever i bind some data with grid or list in SL/WPF as it is easy and more understandable. why dont you try Binding coustom list to your code?? For examlple.. take and Filed like say String HyperLinkNaviagtion

when you get values fro service then befor assigning list to your grid, iterate on all of your items and assign HyperLinkNaviagtion some value like

 if(SomeCondition)
    { 
      // navigaet to google
          HyperLinkNaviagtion ="www.google.com";
    } 
 else 
   { 
     // navigaet to yahoo
       HyperLinkNaviagtion ="www.yahoo.com";
   }

and in Xaml, do the following

NavigateUri="{Binding HyperLinkNaviagtion }"

It is don, you can control almost every thing like this =) this might be not the best but in my case it is easiest and tension free too .

Upvotes: 0

Vlad
Vlad

Reputation: 35594

This must be correct:

<Button x:Name="cancelButton" IsEnabled="{Binding IsNew, Source=SelectedItem}"/>

The question is, where is your SelectedItem? Is it a property of the DataContext, or a property of your control (or of some list inside your control)?

Edit:
For the Control property, the following should do:

<Button x:Name="cancelButton"
        IsEnabled="{Binding SelectedItem.IsNew,
                            RelativeSource={RelativeSource FindAncestor, AncestorType=local:MyControl}}"/>

Upvotes: 1

Related Questions