WPF, Caliburn Micro и Dapper - Datagrid Флажок привязки - PullRequest
1 голос
/ 05 февраля 2020

Я использую Caliburn Micro и Dapper в проекте WPF, где я создаю DataGrid, который я заполняю данными из SQL Таблицы базы данных сервера. Обратите внимание на следующие фрагменты кода:

ChangesModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PTSRDesktopUI.Models
{
    //public class for all changes attributes
    public class ChangesModel
    {
        public int ID { get; set; }
        public string Facility { get; set; }
        public string Controller { get; set; }
        public string ParameterName { get; set; }
        public string OldValue { get; set; }
        public string NewValue { get; set; }
        public DateTime ChangeDate { get; set; }
        public bool Validated { get; set; }
        public DateTime ValidationDate { get; set; }
    }
}

OverviewView.xaml

<!--Datagrid Table-->
<DataGrid Grid.Row="1" x:Name="Changes" CanUserAddRows="False" AutoGenerateColumns="False" HorizontalAlignment="Stretch">
    <DataGrid.Columns>
        <DataGridTextColumn CellStyle="{StaticResource DataGridCellCentered}" IsReadOnly="True" 
                            Header="Facility" Binding="{Binding Path=Facility}"/>
        <DataGridTextColumn CellStyle="{StaticResource DataGridCellCentered}" IsReadOnly="True" 
                            Header="Controller" Binding="{Binding Path=Controller}"/>
        <DataGridTextColumn CellStyle="{StaticResource DataGridCellCentered}" IsReadOnly="True" 
                            Header="Parameter" Binding="{Binding Path=ParameterName}"/>
        <DataGridTextColumn CellStyle="{StaticResource DataGridCellCentered}" IsReadOnly="True" 
                            Header="Old Value" Binding="{Binding Path=OldValue}"/>
        <DataGridTextColumn CellStyle="{StaticResource DataGridCellCentered}" IsReadOnly="True" 
                            Header="New Value" Binding="{Binding Path=NewValue}"/>
        <DataGridTextColumn CellStyle="{StaticResource DataGridCellCentered}" IsReadOnly="True" 
                            Header="Changed Date" Binding="{Binding Path=ChangeDate, 
                            StringFormat='{}{0:dd.MM HH:mm}'}"/>
        <DataGridTemplateColumn CellStyle="{StaticResource DataGridCellCentered}" 
                                Header="Validated" IsReadOnly="True">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate >
                    <CheckBox IsChecked="{Binding Path=Validated}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn CellStyle="{StaticResource DataGridCellCentered}" IsReadOnly="True" 
                            Header="Validation Date" Binding="{Binding Path=ValidationDate, 
                            StringFormat='{}{0:dd.MM HH:mm}'}"/>
        <DataGridTemplateColumn CellStyle="{StaticResource DataGridCellCentered}" Header="Validate">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button x:Name="Validate_Btn" cal:Message.Attach="Validate">Validate</Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

OverviewViewModel.cs

using Caliburn.Micro;
using PTSRDesktopUI.Helpers;
using PTSRDesktopUI.Models;

namespace PTSRDesktopUI.ViewModels
{
    public class OverviewViewModel : Screen
    {

        //Create new Bindable Collection variable of type ChangesModel
        public BindableCollection<ChangesModel> Changes { get; set; }


        public OverviewViewModel()
        {

            //Create connection to DataAccess class
            DataAccess db = new DataAccess();

            //get the changes from DataAccess function and store them as a bindable collection in Changes
            Changes = new BindableCollection<ChangesModel>(db.GetChanges());

        }

        //Validate_Btn click event
        public void Validate()
        {
           //Some Code        
        }

    }
}

DataAccess .cs

//Function to get all changes from database using stored procedures
public List<ChangesModel> GetChanges()
{
    using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(DBHelper.CnnVal("ptsrDB")))
    {
        var output = connection.Query<ChangesModel>("dbo.getChanges").ToList();
        return output;
    }
}

Я использую хранимую процедуру под названием getChanges для получения данных с сервера SQL. Данные отображаются и все отлично работает. Теперь я хочу сделать следующее: во-первых, я хочу, чтобы Validate_Btn был виден только в строках, где CheckBox не отмечен. Во-вторых, если пользователь нажимает Validate_Btn, я хочу изменить CheckBox на флажок, сделать кнопку невидимой и вызвать новую функцию с хранимой процедурой из класса DataAccess, чтобы обновить логическое значение для Validated в таблица базы данных. У кого-нибудь есть идеи, как я могу это сделать?

1 Ответ

1 голос
/ 05 февраля 2020

Чтобы решить первую часть отображения и скрытия Button в зависимости от того, установлен ли флажок CheckBox, необходимо сначала реализовать интерфейс INotifyPropertyChanged в своем классе ChangesModel и повысить значение * 1006. * событие, когда установлено свойство Validated:

public class ChangesModel : INotifyPropertyChanged
{
    public int ID { get; set; }
    public string Facility { get; set; }
    public string Controller { get; set; }
    public string ParameterName { get; set; }
    public string OldValue { get; set; }
    public string NewValue { get; set; }
    public DateTime ChangeDate { get; set; }

    private bool _validated;
    public bool Validated
    {
        get { return _validated; }
        set { _validated = value; NotifyPropertyChanged(); }
    }

    public DateTime ValidationDate { get; set; }

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

}

Затем можно связать свойство Button Visibility со свойством Validated source и использовать конвертер для преобразования между * Значение 1014 * и значение перечисления Visibility:

<DataGridTemplateColumn Header="Validate">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <DataTemplate.Resources>
                <BooleanToVisibilityConverter x:Key="converter" />
            </DataTemplate.Resources>
            <Button x:Name="Validate_Btn" cal:Message.Attach="Validate"
                    Visibility="{Binding Validated, Converter={StaticResource converter}}">Validate</Button>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Вы также можете установить UpdateSourcePropertyTrigger в привязке CheckBox для свойства источника, которое должно быть установлено немедленно:

<CheckBox IsChecked="{Binding Path=Validated, UpdateSourceTrigger=PropertyChanged}" />

Чтобы ваш Validate() вызывался при нажатии кнопки, вы можете привязать присоединенное свойство Bind.Model к модели представления:

<Button x:Name="Validate"
        cal:Bind.Model="{Binding DataContext, 
            RelativeSource={RelativeSource AncestorType=DataGrid}}">Validate</Button>

Для объединения привязок требуется указать источник Visibility переплет:

<Button x:Name="Validate"
    Visibility="{Binding DataContext.Validated, 
       Converter={StaticResource converter}, RelativeSource={RelativeSource AncestorType=DataGridCell}}"
    cal:Bind.Model="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGrid}}">Validate</Button>
...