Datagrid更改时如何启用按钮?

时间:2018-10-15 11:27:44

标签: c# wpf mvvm datagrid

当Datagrid中的任何数据更改时,如何启用按钮?

    <DataGrid x:Name="GlobalShortcutsDataGrid" 
            ItemsSource="{Binding GlobalShortcutsObservableCollection}"
            SelectedItem="{Binding SelectedRow}"
            AutoGenerateColumns="False">

        <DataGrid.Columns >
            <DataGridTextColumn Header="Shortcut Name" Binding="{Binding ShortcutName}"></DataGridTextColumn>
            <DataGridTextColumn Header="Shortcut Path" Binding="{Binding FilePath}"></DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

    <Button x:Name="buttonSave" IsEnabled="False"
            Command="{Binding SaveCommand}"
            Content="Save Edits">

        <Button.Style>
            <Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
                <Style.Triggers>
                    // I'm not sure how to check for datagrid changes here
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>

2 个答案:

答案 0 :(得分:2)

我建议您进行以下更改:

XAML

<DataGrid x:Name="GlobalShortcutsDataGrid" 
        ItemsSource="{Binding GlobalShortcutsObservableCollection}"
        SelectedItem="{Binding SelectedRow}"
        AutoGenerateColumns="False">

    <DataGrid.Columns >
        <DataGridTextColumn Header="Shortcut Name" Binding="{Binding ShortcutName}"></DataGridTextColumn>
        <DataGridTextColumn Header="Shortcut Path" Binding="{Binding FilePath}"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

<Button x:Name="buttonSave" IsEnabled="{Binding IsButtonSaveEnabled}"
        Command="{Binding SaveCommand}"
        Content="Save Edits"/>

您的VM

创建新的bool属性:

public bool IsButtonSaveEnabled
   {
     get
       {
         return yourLogicToBeEnabled;
       }
   }

然后在您的FilePathShortcutName中设置(我不知道使用哪个按钮来更改按钮的状态),只需增加IsButtonSaveEnabled的更改即可。


编辑 :更改了XAML,因为我认为您想隐藏它而不更改启用状态。只需卸下转换器。


编辑:要解决您的情况,我将创建一个这样的类:

public class YourParentVMDataSource
{
    private YourParentVM yourParentVM;
    private GlobalShortcutsVM globalShorcutsVM;

    public YourParentVMDataSource(GlobalShortcutsVM globalShortcutsVm, YourParentVM yourParentVM)
    {
        this.globalShorcutsVM = globalShortcutsVm;
        this.yourParentVM = yourParentVM;
    }

    public void CreateDataSource()
    {
        this.globalShorcutsVM.Model.PropertyChanged += this.OnGlobalShortcutsModelPropertyChanged
    }

    private void OnGlobalShortcutsModelPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case "ShortcutName":
                this.yourParentVM.RaisePropertyChanged("IsButtonSaveEnabled");
                break;
            case "FilePath":
                this.yourParentVM.RaisePropertyChanged("IsButtonSaveEnabled");
                break;
        }
    }
}

yourParentVM是您的“主要” VM,GlobalShortcutsVM是我认为您用来填充DataGrid的VM(您应该有一个ObservableCollection<GlobalShortcutsVM> GlobalShortcutsObservableCollection

每当您在GlobalShortcutsObservableCollection模型中发生任何更改时,它将引发该事件并由您处理。在处理程序中,引发父VM的属性。

创建“主”虚拟机后,应该创建这个新类并调用CreateDataSource方法。

答案 1 :(得分:1)

有几种方法可以实现它。首选方法是在ViewModel中执行此操作,并将其绑定到某些ViewModel属性IsSaveEnabled

为您的CellEditEnding处理DataGrid事件的另一种方法。

<DataGrid x:Name="GlobalShortcutsDataGrid" CellEditEnding="dataGrid_CellEditEnding"
    ItemsSource="{Binding GlobalShortcutsObservableCollection}"
    SelectedItem="{Binding SelectedRow}"
    AutoGenerateColumns="False">

    <DataGrid.Columns >
        <DataGridTextColumn Header="Shortcut Name" Binding="{Binding ShortcutName}"></DataGridTextColumn>
        <DataGridTextColumn Header="Shortcut Path" Binding="{Binding FilePath}"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

<Button x:Name="buttonSave" IsEnabled="False"
    Command="{Binding SaveCommand}"
    Content="Save Edits">
</Button>

后面的代码:

private void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    var tb = e.EditingElement as TextBox;
    var bindingIsDirty = tb.GetBindingExpression(TextBox.TextProperty).IsDirty;
    buttonSave.IsEnabled |= (bindingIsDirty && e.EditAction == DataGridEditAction.Commit);
}

您还可以将功能背后的代码移动到具有某些依赖项属性IsDirty的行为,并将Button.IsEnabled绑定到此属性:

<DataGrid x:Name="GlobalShortcutsDataGrid"
    ItemsSource="{Binding GlobalShortcutsObservableCollection}"
    SelectedItem="{Binding SelectedRow}"
    AutoGenerateColumns="False">
            <i:Interaction.Behaviors>
                <local:DataGridChangedBehavior IsDataGridChanged="{Binding Path=IsEnabled, ElementName=buttonSave}"/>
            </i:Interaction.Behaviors>
            <DataGrid.Columns >
        <DataGridTextColumn Header="Shortcut Name" Binding="{Binding ShortcutName}"></DataGridTextColumn>
        <DataGridTextColumn Header="Shortcut Path" Binding="{Binding FilePath}"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

<Button x:Name="buttonSave" IsEnabled="False"
    Command="{Binding SaveCommand}"
    Content="Save Edits">
</Button>


public class DataGridChangedBehavior: Behavior<DataGrid>
{
    public bool IsDataGridChanged
    {
        get { return (bool)GetValue(IsDataGridChangedProperty); }
        set { SetValue(IsDataGridChangedProperty, value); }
    }

    public static readonly DependencyProperty IsDataGridChangedProperty =
        DependencyProperty.Register("IsDataGridChanged", typeof(bool), typeof(DataGridChangedBehavior), new PropertyMetadata(0));

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.CellEditEnding += dataGrid_CellEditEnding;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.CellEditEnding -= dataGrid_CellEditEnding;
        base.OnDetaching();
    }

    private void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        var tb = e.EditingElement as TextBox;
        var bindingIsDirty = tb.GetBindingExpression(TextBox.TextProperty).IsDirty;
        IsDataGridChanged |= (bindingIsDirty && e.EditAction == DataGridEditAction.Commit);
    }
}