Как включить кнопку при изменении Datagrid? - PullRequest
0 голосов
/ 15 октября 2018

Как включить кнопку, если какие-либо данные в сетке данных изменяются?

    <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 голосов
/ 15 октября 2018

Есть несколько способов достичь этого.Предпочтительным способом является сделать это в 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);
    }
}
0 голосов
/ 15 октября 2018

Я предлагаю вам внести следующие изменения:

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"/>

YourVM

Создать новый булсвойство:

public bool IsButtonSaveEnabled
   {
     get
       {
         return yourLogicToBeEnabled;
       }
   }

затем в вашем наборе FilePath или ShortcutName (я не знаю, какой из них используется для изменения состояния кнопки), просто увеличьте изменение 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 - ваша "основная" ВМ, а GlobalShortcutsVM - это виртуальная машина, которую я предполагал использовать для заполнения DataGrid (у вас должно быть ObservableCollection<GlobalShortcutsVM> GlobalShortcutsObservableCollection)

Каждый раз, когда что-то изменяется в вашей модели GlobalShortcutsObservableCollection, оно вызывает событие, и вы обрабатываете его.В обработчике вы вызываете свойство родительской виртуальной машины.

Вы должны создать этот новый класс и вызвать метод CreateDataSource после создания своей "основной" виртуальной машины.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...