Привязка для пользовательского элемента управления работает в GridView, но не в FormView - PullRequest
2 голосов
/ 07 марта 2012

Я превращаю некоторые бумажные формы в веб-формы, и одним из моих требований является наличие группы флажков «Да / Нет», которые также могут отслеживать, если выбор не был сделан.Поэтому я не могу просто использовать один CheckBox, связанный с битовым полем в Sql Server, потому что он не отслеживает, игнорировал ли пользователь поле или нет.

Чтобы решить мою проблему, я обернул два флажка вКонтроль ASCX.Затем я создал публичное свойство Checked в своем элементе управления ASCX.Из этого свойства я возвратил «True», если установлен флажок «true», «False» - флажок «false» и пустая строка, если флажок не установлен.

Когда я помещаю этот элемент управления в GridView ипривязать его к битовому полю с помощью GridView SqlDataSource все работает отлично.Когда я связываю тот же элемент управления в FormView, хотя обновление FormView устанавливает для нетронутых элементов управления значение False.Я прошел через мою логику управления, и она правильно передает пустую строку, поэтому кажется, что FormView переопределяет значение перед отправкой его в хранимую процедуру.

Есть ли способ заставить эту работу работать в FormViewили мне придется рефакторинг, чтобы использовать что-то вроде поля int для отслеживания трех опций: 0 = нет выбора, 1 = true, 2 = false или что-то в этом роде?Я предоставил код для моего элемента управления ASCX ниже для справки.

public partial class controls_yesNoCheck : System.Web.UI.UserControl
{
    public string Checked
    {
        get
        {
            if (ckbNo.Checked)
                return "false";
            if (ckbYes.Checked)
                return "true";
            else
                return "";
        }
        set
        {
            if (value == "")
            {
                ckbNo.Checked = false;
                ckbYes.Checked = false;
            }
            else if (value == "True" || value == "true")
            {
                ckbYes.Checked = true;
                ckbNo.Checked = false;
            }
            else
            {
                ckbNo.Checked = true;
                ckbYes.Checked = false;
            }
        }
    }
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void noChecked(object sender, EventArgs e)
    {
        ckbYes.Checked = false;
    }

    protected void yesChecked(object sender, EventArgs e)
    {
        ckbNo.Checked = false;
    }
}

Редактировать: внешний вид элемента управления выглядит так, я оставил методы CheckChanged вне предыдущего блока кода, так как их функциональность нене влияет на эту проблему.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="yesNoCheck.ascx.cs" Inherits="controls_yesNoCheck" %>

<asp:CheckBox ID="ckbYes" runat="server" Text="Yes" AutoPostBack="true" OnCheckedChanged="yesChecked" />
<asp:CheckBox ID="ckbNo" runat="server" Text="No" AutoPostBack="true" OnCheckedChanged="noChecked" />

Ответы [ 2 ]

2 голосов
/ 07 марта 2012

Задумывались ли вы об использовании обнуляемых типов ?

Тогда вы могли бы иметь гораздо более простой код, и он лучше соответствовал бы БД, поскольку SQL Server имеет тип битов, допускающих значение NULL. Примерно так должно работать:

public bool? Checked {get; private set;}
public void setChecked(String value)
{
    if (value == "")
       _checked = null;
    else if (value.ToLower() == "true")
       _checked = true;
    else
       _checked = false;
}

Исходя из того, где вы говорите, что ошибка не возникает, и вашего кода выше, я бы поспорил, что есть некоторая проблема с вашим преобразованием из строки в int для вставки в базу данных. Опять же, переключение на приведенный выше код должно решить эту проблему.

0 голосов
/ 08 марта 2012

Для тех, кто может наткнуться на это позже, @randomben и @jonraynot, вероятно, лают дерево «наилучшей практики», но я смог исправить свою проблему, изменив свою хранимую процедуру.

Возможно, это не самое лучшее решение, но вот оно. Я изменил параметр в моей хранимой процедуре обновления с битового поля на nvarchar (5), а затем с помощью следующего оператора CASE (упрощенного для прояснения сути)

UPDATE table_name 
SET bit_column_name = CASE 
    WHEN @bit_column_name = 'True' THEN 'True'
    WHEN @bit_column_name = 'False' THEN 'False'
    ELSE NULL
    END

С этим изменением хранимой процедуры мне не пришлось вносить никаких изменений в код, который я опубликовал ранее.

...