Модуль C # DotNetNuke: доступ к данным в CodeBehind для GridView - PullRequest
0 голосов
/ 28 января 2011

Я пытаюсь написать виджет для DotNetNuke на C #. Это мой первый крупный проект на C #, и, хотя я думаю, что уже освоился, я все еще сталкиваюсь с парой проблем, связанных с WebForms. В частности, у меня проблемы с GridView, и хотя я чувствую, что нахожусь там на 90%, последние 10% - убийца.

Во-первых, соответствующие биты из моего файла .ascx:

<asp:ObjectDataSource ID="objDataSource" runat="server" TypeName="MyCompany.Modules.Discovery.DiscoveryController" SelectMethod="GetDiscoverys" UpdateMethod="UpdateDiscovery" DeleteMethod="DeleteDiscovery">
    <SelectParameters>
        <asp:QueryStringParameter Name="ModuleId" QueryStringField="mid" />
    </SelectParameters>
    <UpdateParameters>
        <asp:QueryStringParameter Name="ModuleId" QueryStringField="mid" />
    </UpdateParameters>
    <DeleteParameters>
        <asp:QueryStringParameter Name="ModuleId" QueryStringField="mid" />
    </DeleteParameters>
</asp:ObjectDataSource>
<!-- Unrelated code... -->
<asp:GridView ID="grdDiscoverys" runat="server" DataSourceID="objDataSource" EnableModelValidation="True" AutoGenerateColumns="false" AutoGenerateEditButton="true" AutoGenerateDeleteButton="true" DataKeyNames="ItemId">
    <Columns>
        <asp:BoundField DataField="ItemId" HeaderText="#" ReadOnly="true" />
        <asp:BoundField DataField="Title" HeaderText="Title" />
        <asp:TemplateField HeaderText="Image">
            <ItemTemplate>
                <%# Eval("Image") %>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:DropDownList ID="ddlEditImage" runat="server" title="Image" OnDataBinding="cmdPopulateImages_prebind" OnLoad="cmdPopulateImages_load" DataValueField="Key" DataTextField="Value" SelectedValue='<%# Bind("Image")%>' />
            </EditItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="Link" HeaderText="Link" />
    </Columns>
</asp:GridView>

Теперь несколько важных моментов из моего файла CodeBehind:

protected void cmdPopulateImages_load(object sender, EventArgs e)
{
    try
    {
        ((System.Web.UI.WebControls.DropDownList)sender).DataSource = GetFileDictionary();
    }
    catch (Exception exc)
    {
        //Module failed to load 
        Exceptions.ProcessModuleLoadException(this, exc);
    }
}

protected void cmdPopulateImages_prebind(object sender, EventArgs e)
    {
    try
    {
        ((System.Web.UI.WebControls.DropDownList)sender).SelectedValue = "-1";
    }
    catch (Exception exc)
    {
        //Module failed to load 
        Exceptions.ProcessModuleLoadException(this, exc);
    }
}

protected Dictionary<int, string> GetFileDictionary()
{
    // Folder ID where images will be grabbed from.  Will be put in settings.
    int intFolderId = 20;
    // Extensions that are allowed to be seen in the list.  Will be put in settings.
    List<string> slValidExtensions = new List<string>("gif,jpg,jpeg,png".Split(','));
    slValidExtensions.ForEach(delegate(string ext) { ext.Trim(); });

    // Grab a list of files and put it in a dictionary.
    ArrayList alFiles = FileSystemUtils.GetFilesByFolder(PortalId, intFolderId);

    Dictionary<int, string> dFiles = new Dictionary<int, string>();
    dFiles.Add(-1, "---");

    foreach (FileInfo fiFile in alFiles)
    {
        // Make sure we are looking at a valid extension
        if (slValidExtensions.Contains(fiFile.Extension))
        {
            dFiles.Add(fiFile.FileId, fiFile.FileName);
        }
    }

    return dFiles;
}

Теперь, на мои вопросы:

  1. Когда вы не редактируете столбец, вы видите изображение. Однако, поскольку это идентификатор, а не фактический файл, он не очень информативен. Мой план атаки здесь состоит в том, чтобы превратить этот Eval в метку, которая запускает метод в codebehind onRender, который будет захватывать связанный файл для этого идентификатора и записывать его в .Text метки ... либо так, либо выписывать «Отсутствует изображение», если идентификатор не может быть найден (например, если пользователь удалил изображение). Однако проблема в том, что когда я на самом деле в методе для события, основанного на этой метке, я не знаю, как получить доступ к данным для этой конкретной строки.
  2. Вы заметите, что в cmdPopulatedImages_Prebind я устанавливаю значение SelectedValue в -1 как побочный продукт чего-то подобного. Я понятия не имею, как получить идентификатор изображения из этого метода, и если идентификатор изображения на самом деле не существует, то модуль выдает ошибку в моем лице, потому что он не существует в раскрывающемся списке. Поэтому я просто устанавливаю его на -1 всегда (что представляет собой пустую запись в словаре данных). Если бы у меня был идентификатор изображения, я мог бы сначала проверить, существует ли оно на самом деле в наборе данных, и если это так, установить его, а если нет, выбрать значение по умолчанию -1.

1 Ответ

1 голос
/ 28 января 2011

Я не отвечаю на ваш вопрос полностью, потому что я не совсем уверен, чего вы пытаетесь достичь, но я приложу все усилия ...

Вы хотите получить свой ImageID, верно?Если ваш запрос возвращает ImageID, добавьте «ImageID» к свойству DataKeyNames вашего GridView.Таким образом, вы можете получить к нему доступ для каждой строки.

Метод, который, на мой взгляд, может оказаться полезным, - это метод RowDataBound.Вызывается, когда каждая строка связана с данными (очевидно ...).Используйте его, это ваш друг.

Из этого метода вы можете вызывать методы и т. Д. Для каждой строки.Вы также можете получить RowIndex, используя e.Row.RowIndex.

Например, чтобы получить свой «ImageID» для заполнения свойства asp: Image ImageUrl, вы можете использовать что-то, например:

var Image1 = (Image)e.Row.FindControl("Image1");
var imageId = Convert.ToInt32(GridView1.DataKeys[e.Row.RowIndex].Values["ImageID"]);
Image1.ImageUrl = GetImageUrlFromId(imageId); //Get the url of your image

Youможет также заполнить ваш выпадающий список, чтобы выбрать правильное значение SelectedValue текущего ImageID.

Надеюсь, это поможет.Код был весь в моей голове, поэтому некоторые вещи могут быть немного не так.

Короче говоря.Используйте свойство DataKeyNames и событие RowDataBound.

...