问:
memory address of numpy elements
See the code snip below

```<code>a = [[1, 2], [3, 4], [5, 6]]
b = a[1]
id(a[1]) == id(b) # True
</code>```

it is easy to understand because address of b and address of a[1] is the same. So if I change element in a a += 1, element in b will changed as well b == [4, 5].

However, if I changed to numpy array, the thing is different

```<code>c = numpy.array(a)
d = c[1]
id(c[1]) == id(d) # False
</code>```

However, if I change element in c c +=1, elements in d will change too (d will change to array([4, 5])), I do not understand two things, 1. why address of d and address of c[1] is different? 2. if the address is different, why the elements changed simutanously?
Anyone could explain? Thanks

答:
Every time the inner ndarray of an ndarray is accessed via indexing like you did with c[1], a new ndarray is created on the fly as a memory (buffer) view. In this line id(c[1]) == id(d), c[1] and d are two individual ndarray instances whose data fields point to the same memory address (called "data area" in numpy doc). Consider the following:

a = [[1, 2], [3, 4], [5, 6]]
c = np.array(a)
d = c[0]
e = c[0]
f = c[1]
print(id(d) == id(e)) # False
print(d.__array_interface__['data'][0] == e.__array_interface__['data'][0]) # True
print(d.__array_interface__['data'][0] == f.__array_interface__['data'][0]) # False
```

The location of the data held by each ndarray can be found in the array interface. And because d and e point to the same data at the same memory address, the data address will be identical. Conversely, d and f do not point to the same data, so their pointers are different.

Title: memory address of numpy elements

Body:
See the code snip below

a = [[1, 2], [3, 4], [5, 6]]
b = a[1]
id(a[1]) == id(b) # True

it is easy to understand because address of b and address of a[1] is the same. So if I change element in a a += 1, element in b will changed as well b == [4, 5].

However, if I changed to numpy array, the thing is different

c = numpy.array(a)
d = c[1]
id(c[1]) == id(d) # False

However, if I change element in c c +=1, elements in d will change too (d will change to array([4, 5])), I do not understand two things, 1. why address of d and address of c[1] is different? 2. if the address is different, why the elements changed simutanously?
Anyone could explain? Thanks

Body:
Every time the inner ndarray of an ndarray is accessed via indexing like you did with c[1], a new ndarray is created on the fly as a memory (buffer) view. In this line id(c[1]) == id(d), c[1] and d are two individual ndarray instances whose data fields point to the same memory address (called "data area" in numpy doc). Consider the following:

a = [[1, 2], [3, 4], [5, 6]]
c = np.array(a)
d = c[0]
e = c[0]
f = c[1]
print(id(d) == id(e)) # False
print(d.__array_interface__['data'][0] == e.__array_interface__['data'][0]) # True
print(d.__array_interface__['data'][0] == f.__array_interface__['data'][0]) # False

The location of the data held by each ndarray can be found in the array interface. And because d and e point to the same data at the same memory address, the data address will be identical. Conversely, d and f do not point to the same data, so their pointers are different.


来源: stackexchange

问:
TypeError: Object of type WorkItem is not JSON serializable
I received this error after running the script below. I would like to create a json file through the result that is generated in this script. What can I do to correct this problem?

I tried to do it via API but I couldn't get the fields I need from this DevOps table.

```<code>from azure.devops.connection import Connection
from msrest.authentication import BasicAuthentication
from azure.devops.v5_1.work_item_tracking.models import Wiql
import json

token = 'xxx'
team_instance = 'https://dev.azure.com/xxx'

credentials = BasicAuthentication("", token)
connection = Connection(base_url=team_instance, creds=credentials)

def print_work_items(work_items):
    for work_item in work_items:
        with open('teste_project.json', 'w') as json_file:
            json.dump(work_items, json_file)

wit_client = connection.clients.get_work_item_tracking_client()

def get_TC_from_query(query):
    query_wiql = Wiql(query=query)
    results = wit_client.query_by_wiql(query_wiql).work_items
    # WIQL query gives a WorkItemReference => we get the corresponding WorkItem from id
    work_items = (wit_client.get_work_item(int(result.id)) for result in results)
    print_work_items(work_items)

get_TC_from_query(
    """\
SELECT *
FROM workitems
WHERE
        [System.TeamProject] = 'xxx'
        and [System.WorkItemType] = 'Product Backlog Item'
        and [System.State] = 'Done'
ORDER BY [System.ChangedDate] DESC
"""
)
</code>```

TypeError: Object of type WorkItem is not JSON serializable

答:
The following produces a generator, which JSON can not serialize:

```<code>work_items = (wit_client.get_work_item(int(result.id)) for result in results)
</code>```

You can instead make work_items a list, which JSON can serialize:

```<code>work_items = [wit_client.get_work_item(int(result.id)) for result in results]
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I received this error after running the script below. I would like to create a json file through the result that is generated in this script. What can I do to correct this problem?

I tried to do it via API but I couldn't get the fields I need from this DevOps table.

from azure.devops.connection import Connection
from msrest.authentication import BasicAuthentication
from azure.devops.v5_1.work_item_tracking.models import Wiql
import json

token = 'xxx'
team_instance = 'https://dev.azure.com/xxx'

credentials = BasicAuthentication("", token)
connection = Connection(base_url=team_instance, creds=credentials)

def print_work_items(work_items):
    for work_item in work_items:
        with open('teste_project.json', 'w') as json_file:
            json.dump(work_items, json_file)

wit_client = connection.clients.get_work_item_tracking_client()

def get_TC_from_query(query):
    query_wiql = Wiql(query=query)
    results = wit_client.query_by_wiql(query_wiql).work_items
    # WIQL query gives a WorkItemReference => we get the corresponding WorkItem from id
    work_items = (wit_client.get_work_item(int(result.id)) for result in results)
    print_work_items(work_items)

get_TC_from_query(
    """\
SELECT *
FROM workitems
WHERE
        [System.TeamProject] = 'xxx'
        and [System.WorkItemType] = 'Product Backlog Item'
        and [System.State] = 'Done'
ORDER BY [System.ChangedDate] DESC
"""
)

TypeError: Object of type WorkItem is not JSON serializable

Body:
The following produces a generator, which JSON can not serialize:

work_items = (wit_client.get_work_item(int(result.id)) for result in results)

You can instead make work_items a list, which JSON can serialize:

work_items = [wit_client.get_work_item(int(result.id)) for result in results]


问:
jquery help with css() and animate()
I have this nav system,

```<code><nav id="mainnav">
    <ul>
        <li<?php if ( $this->uri->segment(1) == '' ): ?> class="active" <?php endif; ?>><a href="">Jobwall</a></li>
        <li<?php if ( $this->uri->segment(1) == 'jobfeed' ): ?> class="active" <?php endif; ?>><a href="">Live Job Feed</a></li>
        <li<?php if ( $this->uri->segment(1) == 'tutorials' ): ?> class="active" <?php endif; ?>><a href="">Tutorials</a></li>
        <li<?php if ( $this->uri->segment(1) == 'services' ): ?> class="active" <?php endif; ?>><a href="">Employer Services</a></li>
    </ul>
    <section id="progress"></section>
</nav>
</code>```

based on the uri the li gets an active class, and based on that active a background image moves to show which page is active, however this only works when I use the CSS function jquery link so,

```<code>if($("#mainnav li:eq(0)").hasClass('active'))
{
    $("#progress").css({backgroundPosition: '-883px 0px'})
}

if($("#mainnav li:eq(1)").hasClass('active'))
{
    alert("hello");
    $("#progress").css({backgroundPosition: '-783px 0px'})
}

if($("#mainnav li:eq(2)").hasClass('active'))
{
    $("#progress").css({backgroundPosition: '-702px 0px'})
}

if($("#mainnav li:eq(3)").hasClass('active'))
{
    $("#progress").css({backgroundPosition: '-567px 0px'})
}
</code>```

If I use,

```<code>if($("#mainnav li:eq(0)").hasClass('active'))
{
    $("#progress").animate({backgroundPosition: '-883px 0px'})
}

if($("#mainnav li:eq(1)").hasClass('active'))
{
    alert("hello");
    $("#progress").animate({backgroundPosition: '-783px 0px'})
}

if($("#mainnav li:eq(2)").hasClass('active'))
{
    $("#progress").animate({backgroundPosition: '-702px 0px'})
}

if($("#mainnav li:eq(3)").hasClass('active'))
{
    $("#progress").animate({backgroundPosition: '-567px 0px'})
}
</code>```

then nothing happens and my background-position is 0px 0px why?

答:
For each of these lines change backgroundPosition to 'background-position', for example:

```<code>$("#progress").css({'background-position': '-883px 0px'});
</code>```

ContentLicense: CC BY-SA 3.0

Title: jquery help with css() and animate()

Body:
I have this nav system,

        <li<?php if ( $this->uri->segment(1) == '' ): ?> class="active" <?php endif; ?>>Jobwall

        <li<?php if ( $this->uri->segment(1) == 'jobfeed' ): ?> class="active" <?php endif; ?>>Live Job Feed

        <li<?php if ( $this->uri->segment(1) == 'tutorials' ): ?> class="active" <?php endif; ?>>Tutorials

        <li<?php if ( $this->uri->segment(1) == 'services' ): ?> class="active" <?php endif; ?>>Employer Services

based on the uri the li gets an active class, and based on that active a background image moves to show which page is active, however this only works when I use the CSS function jquery link so,

if($("#mainnav li:eq(0)").hasClass('active'))
{
    $("#progress").css({backgroundPosition: '-883px 0px'})
}

if($("#mainnav li:eq(1)").hasClass('active'))
{
    alert("hello");
    $("#progress").css({backgroundPosition: '-783px 0px'})
}

if($("#mainnav li:eq(2)").hasClass('active'))
{
    $("#progress").css({backgroundPosition: '-702px 0px'})
}

if($("#mainnav li:eq(3)").hasClass('active'))
{
    $("#progress").css({backgroundPosition: '-567px 0px'})
}

If I use,

if($("#mainnav li:eq(0)").hasClass('active'))
{
    $("#progress").animate({backgroundPosition: '-883px 0px'})
}

if($("#mainnav li:eq(1)").hasClass('active'))
{
    alert("hello");
    $("#progress").animate({backgroundPosition: '-783px 0px'})
}

if($("#mainnav li:eq(2)").hasClass('active'))
{
    $("#progress").animate({backgroundPosition: '-702px 0px'})
}

if($("#mainnav li:eq(3)").hasClass('active'))
{
    $("#progress").animate({backgroundPosition: '-567px 0px'})
}

then nothing happens and my background-position is 0px 0px why?

Body:
For each of these lines change backgroundPosition to 'background-position', for example:

$("#progress").css({'background-position': '-883px 0px'});


问:
Prevent Postback with custom jQuery confirm implementation on asp:LinkButton
I have a LinkButton that executes on the server and changes the page.  Historically, I've had a confirm message box that executes OnClientClick to ensure the user would like to navigate away.

So far it looks like this:

ASP.NET:

<asp:LinkButton runat="server" ID="ChangePage" Text="Change page"
                OnClientClick="confirm('are you sure you want to change page?');"
                OnClick="Navigate" >
    Change Page
</asp:LinkButton>
```

<p><strong>HTML Output</strong>:</p>

<pre class="lang-html prettyprint-override"><code>
    Change page

</code>```

This all works fine like this. The trouble is that I'm trying to replace all confirm boxes with a prettier jQuery-UI implementation like this:

window.confirm = function (message, obj) {
    $('
')
    .attr({ title: 'Webpage Confirm'})
    .html(message)
    .dialog({
        resizable: false,
        modal: true,
        width: 500,
        buttons: {
            "OK": function () {
                __doPostBack(obj, '');
                $(this).dialog('close');
                return true;
            },
            "Cancel": function () {
                $(this).dialog('close');
                return false;
            }
        }
    });
};
```

I believe this has to do with the fact that the confirm dialog operates synchronously, while jQuery dialogs occur asynchronously.  However, I thought setting modal: true would cause it to wait for a response.

How can I override window.confirm to get consistent behavior?

答:
Add this to OK action:

```<code>    var href = $(obj).attr("href");
window.location.replace(href);
window.navigator.location(href);
return true;
</code>```

And remove __postback line

it works with me

Body:
I have a LinkButton that executes on the server and changes the page.  Historically, I've had a confirm message box that executes OnClientClick to ensure the user would like to navigate away.

So far it looks like this:

ASP.NET:

<asp:LinkButton runat="server" ID="ChangePage" Text="Change page"
                OnClientClick="confirm('are you sure you want to change page?');"
                OnClick="Navigate" >
    Change Page
</asp:LinkButton>

HTML Output:

    Change page

This all works fine like this. The trouble is that I'm trying to replace all confirm boxes with a prettier jQuery-UI implementation like this:

window.confirm = function (message, obj) {
    $('
')
    .attr({ title: 'Webpage Confirm'})
    .html(message)
    .dialog({
        resizable: false,
        modal: true,
        width: 500,
        buttons: {
            "OK": function () {
                __doPostBack(obj, '');
                $(this).dialog('close');
                return true;
            },
            "Cancel": function () {
                $(this).dialog('close');
                return false;
            }
        }
    });
};

I believe this has to do with the fact that the confirm dialog operates synchronously, while jQuery dialogs occur asynchronously.  However, I thought setting modal: true would cause it to wait for a response.

How can I override window.confirm to get consistent behavior?

Body:
Add this to OK action:

    var href = $(obj).attr("href");
window.location.replace(href);
window.navigator.location(href);
return true;

And remove __postback line

it works with me


问:
How to add back the sort arrow after applying background of Column headers
After applying background color to columnheaders, the sort arrow is missing. How to add it back?</p>

答:
Here is a blog post that breaks down the template process for the DataGridColumnHeader very well and provides a visual of the result. Blog post by Terry Hutt

his demonstrates the default column header. Click on the column headers to resort the columns. You can also resequence the columns by dragging the header and resize them by dragging hidden thumbs at either end of the header The header itself obviously a button with an optional sort indicator above the text. It looks pretty nasty.

Let's try to change the background of the header so it isn't so obviously a button. The DataGrid has a ColumnHeaderStyle attribute. We could use that but for simplicity let's create a default style for our column headers by adding this to the XAML...

```<code><Window.Resources>
    <Style TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="Background" Value="LightGray"/>
    </Style>
</Window.Resources>
</code>```

If you run the project with the new style the header looks much better. But wait - where did our sort indicators go? It turns out that the DataGridColumnHeader is deliberately styled so that the sort indicator is hidden if you change the background color. Sometimes I just don't understand how Microsoft stays in business. Why would you style such an ugly control and then break other critical functionality when the developer tries to fix it.

We have to re-template the DataGridColumnHeader. While we're in there, lets have some fun! This is what we're going to do...

Change the background color
Use a border to create an underline
Change the color of the border when the mouse is over the header
Move the sort indicator to the side of the header text instead of above
Make the column width thumbs invisible but change the cursor when it's over them

Step 1 - Beef the style up so it looks like this...

```<code><Style TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="MinWidth" Value="0"/>
    <Setter Property="MinHeight" Value="0"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Background" Value="LightGray"/>
    <Setter Property="Cursor" Value="Hand"/>
</Style>
</code>```

Step 2 - Write the ControlTemplate that defines the header area, the sort indicator, the border, and the thumbs. The Grid controls the layout of the header, with the Content area on the left and the Sort Indicator on the right. Note the Sort Indicator is defined using a Path. The two rectangles produce a visible left and right edge for the column headers. The Thumbs must be defined and allow the user to resize the columns. We will define the ThumbStyle later. Notice the name of the Border. We need this so we can alter it using triggers in step 3. Add this before the closing Style tag.

```<code><Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Border x:Name="BackgroundBorder" BorderThickness="0,0,0,2"
                        Background="LightGray"
                        BorderBrush="Black"
                        Grid.ColumnSpan="2"/>
                <ContentPresenter Margin="6,3,6,3" VerticalAlignment="Center"/>
                <Path x:Name="SortArrow" Visibility="Collapsed" Data="M 0,0 L 1,0 0.5,1 z" Stretch="Fill"
                     Grid.Column="1" Width="8" Height="6" Fill="Black" Margin="0,0,8,0"
                      VerticalAlignment="Center" RenderTransformOrigin="0.5, 0.4"/>
                <Rectangle Width="1" Fill="#EEEEEE" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                <Rectangle Width="1" Margin="0,0,1,0" Fill="#DDDDDD" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ThumbStyle}"/>
                <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1" HorizontalAlignment="Right" Style="{StaticResource ThumbStyle}"/>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>
</code>```

Step 3 - Add triggers to change the color of the border when the mouse moves over the column header. Add the following triggers after the Grid closing tag.

```<code><ControlTemplate.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
        <Setter TargetName="BackgroundBorder" Property="Background" Value="LightGray"/>
        <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="Orange"/>
    </Trigger>
</ControlTemplate.Triggers>
</code>```

Step 4 - Add triggers to display and/or rotate the Sort Indicator when the column is sorted.

```<code><Trigger Property="SortDirection" Value="Ascending">
    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
    <Setter TargetName="SortArrow" Property="RenderTransform">
        <Setter.Value>
            <RotateTransform Angle="180"/>
        </Setter.Value>
    </Setter>
</Trigger>
<Trigger Property="SortDirection" Value="Descending">
    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
</Trigger>
</code>```

Step 5 - Hide the LeftHeaderGripper in column 0 - we don't need it.

```<code><Trigger Property="DisplayIndex" Value="0">
    <Setter TargetName="PART_LeftHeaderGripper" Property="Visibility" Value="Collapsed"/>
</Trigger>
</code>```

As promised, here is the ThumbStyle definition. Insert it above the DataGridColumnHeader style. I use an invisible rectangle with a cursor of SizeWE. You could color it or use something completely different if you chose.

```<code><Style TargetType="{x:Type Thumb}" x:Key="ThumbStyle">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Thumb}">
                <Rectangle Width="1" Stroke="Transparent" Cursor="SizeWE"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
</code>```

** **UPDATE:  Style Entries Combined Together **

```<code><FontFamily x:Key="Corp_FontFamily">Segoe UI</FontFamily>
<clr:Double x:Key="Corp_FontSize">13</clr:Double>
<Style TargetType="{x:Type Control}" x:Key="baseStyle">
    <Setter Property="FontFamily" Value="{StaticResource Corp_FontFamily}" />
    <Setter Property="FontSize" Value="{StaticResource Corp_FontSize}" />
</Style>

<Color x:Key="CorpBlue_T1S1" A="255" R="172" G="180" B="196"/>
<SolidColorBrush x:Key="Brush_CorpBlue_T1S1" Color="{StaticResource CorpBlue_T1S1}"/>

<Color x:Key="CLR_Green" A="255" R="220" G="239" B="202"/>
<SolidColorBrush x:Key="YourCompany_HeaderColumnDefaultBackground" Color="{StaticResource CLR_Green}"/>

<Style TargetType="DataGridColumnHeader" x:Key="DG_Hdr_Base" BasedOn="{StaticResource baseStyle}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="MinWidth" Value="0"/>
    <Setter Property="MinHeight" Value="0"/>
    <Setter Property="Background" Value="{StaticResource YourCompany_HeaderColumnDefaultBackground}"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="Padding" Value="5"/>
    <Setter Property="BorderThickness" Value="0 0 1 0"/>
    <Setter Property="BorderBrush" Value="DarkGray"/>
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="TextBlock.TextAlignment" Value="Center" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="DataGridColumnHeader">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Border x:Name="BackgroundBorder" BorderThickness="0,0,0,2"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Grid.ColumnSpan="2"/>
                    <ContentPresenter Margin="5" VerticalAlignment="Center" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                    <Path x:Name="SortArrow" Visibility="Collapsed" Data="M 0,0 L 1,0 0.5,1 z" Stretch="Fill"
                         Grid.Column="1" Width="8" Height="6" Fill="Black" Margin="0,0,8,0"
                          VerticalAlignment="Center" RenderTransformOrigin="0.5, 0.4"/>
                    <Rectangle Width="1" Fill="DarkGray" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                    <Rectangle Width="1" Margin="0,0,1,0" Fill="DarkGray" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                    <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ThumbStyle}"/>
                    <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1" HorizontalAlignment="Right" Style="{StaticResource ThumbStyle}"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="BackgroundBorder" Property="Background" Value="{StaticResource Brush_CorpBlue_T1S1}"/>
                        <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="{StaticResource ControlHighlightBorderBrush}"/>
                    </Trigger>
                    <Trigger Property="SortDirection" Value="Ascending">
                        <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="SortArrow" Property="RenderTransform">
                            <Setter.Value>
                                <RotateTransform Angle="180"/>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="SortDirection" Value="Descending">
                        <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
                    </Trigger>
                    <Trigger Property="DisplayIndex" Value="0">
                        <Setter TargetName="PART_LeftHeaderGripper" Property="Visibility" Value="Collapsed"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
</code>```

ContentLicense: CC BY-SA 2.5

Body:
Here is a blog post that breaks down the template process for the DataGridColumnHeader very well and provides a visual of the result. Blog post by Terry Hutt

his demonstrates the default column header. Click on the column headers to resort the columns. You can also resequence the columns by dragging the header and resize them by dragging hidden thumbs at either end of the header The header itself obviously a button with an optional sort indicator above the text. It looks pretty nasty.

Let's try to change the background of the header so it isn't so obviously a button. The DataGrid has a ColumnHeaderStyle attribute. We could use that but for simplicity let's create a default style for our column headers by adding this to the XAML...

<Window.Resources>
    <Style TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="Background" Value="LightGray"/>
    </Style>
</Window.Resources>

If you run the project with the new style the header looks much better. But wait - where did our sort indicators go? It turns out that the DataGridColumnHeader is deliberately styled so that the sort indicator is hidden if you change the background color. Sometimes I just don't understand how Microsoft stays in business. Why would you style such an ugly control and then break other critical functionality when the developer tries to fix it.

We have to re-template the DataGridColumnHeader. While we're in there, lets have some fun! This is what we're going to do...

Change the background color
Use a border to create an underline
Change the color of the border when the mouse is over the header
Move the sort indicator to the side of the header text instead of above
Make the column width thumbs invisible but change the cursor when it's over them

Step 1 - Beef the style up so it looks like this...

<Style TargetType="{x:Type DataGridColumnHeader}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="MinWidth" Value="0"/>
    <Setter Property="MinHeight" Value="0"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Background" Value="LightGray"/>
    <Setter Property="Cursor" Value="Hand"/>
</Style>

Step 2 - Write the ControlTemplate that defines the header area, the sort indicator, the border, and the thumbs. The Grid controls the layout of the header, with the Content area on the left and the Sort Indicator on the right. Note the Sort Indicator is defined using a Path. The two rectangles produce a visible left and right edge for the column headers. The Thumbs must be defined and allow the user to resize the columns. We will define the ThumbStyle later. Notice the name of the Border. We need this so we can alter it using triggers in step 3. Add this before the closing Style tag.

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Border x:Name="BackgroundBorder" BorderThickness="0,0,0,2"
                        Background="LightGray"
                        BorderBrush="Black"
                        Grid.ColumnSpan="2"/>
                <ContentPresenter Margin="6,3,6,3" VerticalAlignment="Center"/>
                <Path x:Name="SortArrow" Visibility="Collapsed" Data="M 0,0 L 1,0 0.5,1 z" Stretch="Fill"
                     Grid.Column="1" Width="8" Height="6" Fill="Black" Margin="0,0,8,0"
                      VerticalAlignment="Center" RenderTransformOrigin="0.5, 0.4"/>
                <Rectangle Width="1" Fill="#EEEEEE" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                <Rectangle Width="1" Margin="0,0,1,0" Fill="#DDDDDD" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ThumbStyle}"/>
                <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1" HorizontalAlignment="Right" Style="{StaticResource ThumbStyle}"/>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>

Step 3 - Add triggers to change the color of the border when the mouse moves over the column header. Add the following triggers after the Grid closing tag.

<ControlTemplate.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
        <Setter TargetName="BackgroundBorder" Property="Background" Value="LightGray"/>
        <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="Orange"/>
    </Trigger>
</ControlTemplate.Triggers>

Step 4 - Add triggers to display and/or rotate the Sort Indicator when the column is sorted.

<Trigger Property="SortDirection" Value="Ascending">
    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
    <Setter TargetName="SortArrow" Property="RenderTransform">
        <Setter.Value>
            <RotateTransform Angle="180"/>
        </Setter.Value>
    </Setter>
</Trigger>
<Trigger Property="SortDirection" Value="Descending">
    <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
</Trigger>

Step 5 - Hide the LeftHeaderGripper in column 0 - we don't need it.

<Trigger Property="DisplayIndex" Value="0">
    <Setter TargetName="PART_LeftHeaderGripper" Property="Visibility" Value="Collapsed"/>
</Trigger>

As promised, here is the ThumbStyle definition. Insert it above the DataGridColumnHeader style. I use an invisible rectangle with a cursor of SizeWE. You could color it or use something completely different if you chose.

<Style TargetType="{x:Type Thumb}" x:Key="ThumbStyle">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Thumb}">
                <Rectangle Width="1" Stroke="Transparent" Cursor="SizeWE"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

** **UPDATE:  Style Entries Combined Together **

<FontFamily x:Key="Corp_FontFamily">Segoe UI</FontFamily>
<clr:Double x:Key="Corp_FontSize">13</clr:Double>
<Style TargetType="{x:Type Control}" x:Key="baseStyle">
    <Setter Property="FontFamily" Value="{StaticResource Corp_FontFamily}" />
    <Setter Property="FontSize" Value="{StaticResource Corp_FontSize}" />
</Style>

<Color x:Key="CorpBlue_T1S1" A="255" R="172" G="180" B="196"/>
<SolidColorBrush x:Key="Brush_CorpBlue_T1S1" Color="{StaticResource CorpBlue_T1S1}"/>

<Color x:Key="CLR_Green" A="255" R="220" G="239" B="202"/>
<SolidColorBrush x:Key="YourCompany_HeaderColumnDefaultBackground" Color="{StaticResource CLR_Green}"/>

<Style TargetType="DataGridColumnHeader" x:Key="DG_Hdr_Base" BasedOn="{StaticResource baseStyle}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="MinWidth" Value="0"/>
    <Setter Property="MinHeight" Value="0"/>
    <Setter Property="Background" Value="{StaticResource YourCompany_HeaderColumnDefaultBackground}"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="Padding" Value="5"/>
    <Setter Property="BorderThickness" Value="0 0 1 0"/>
    <Setter Property="BorderBrush" Value="DarkGray"/>
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="TextBlock.TextAlignment" Value="Center" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="DataGridColumnHeader">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Border x:Name="BackgroundBorder" BorderThickness="0,0,0,2"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Grid.ColumnSpan="2"/>
                    <ContentPresenter Margin="5" VerticalAlignment="Center" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                    <Path x:Name="SortArrow" Visibility="Collapsed" Data="M 0,0 L 1,0 0.5,1 z" Stretch="Fill"
                         Grid.Column="1" Width="8" Height="6" Fill="Black" Margin="0,0,8,0"
                          VerticalAlignment="Center" RenderTransformOrigin="0.5, 0.4"/>
                    <Rectangle Width="1" Fill="DarkGray" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                    <Rectangle Width="1" Margin="0,0,1,0" Fill="DarkGray" HorizontalAlignment="Right" Grid.ColumnSpan="2"/>
                    <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ThumbStyle}"/>
                    <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1" HorizontalAlignment="Right" Style="{StaticResource ThumbStyle}"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="BackgroundBorder" Property="Background" Value="{StaticResource Brush_CorpBlue_T1S1}"/>
                        <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="{StaticResource ControlHighlightBorderBrush}"/>
                    </Trigger>
                    <Trigger Property="SortDirection" Value="Ascending">
                        <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
                        <Setter TargetName="SortArrow" Property="RenderTransform">
                            <Setter.Value>
                                <RotateTransform Angle="180"/>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="SortDirection" Value="Descending">
                        <Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
                    </Trigger>
                    <Trigger Property="DisplayIndex" Value="0">
                        <Setter TargetName="PART_LeftHeaderGripper" Property="Visibility" Value="Collapsed"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>


问:
How to use GeometryReader without it filling the View
This is the layout I'm aiming for.

```<code>import SwiftUI
import PlaygroundSupport

struct TestView: View {

    let text: String

    var body: some View {
        Text(self.text)
    }
}

struct ContentView: View {
    var body: some View {
        ZStack {
            TestView(text: "bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla")
                .frame(width: 250)
                .background(Color.red)
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())
</code>```

But I also want to use the GeometryReader and when I put the Text inside the GeometryReader it will take up the full height.

```<code>import SwiftUI
import PlaygroundSupport

struct TestView: View {

    let text: String

    var body: some View {
        GeometryReader { reader in
            Text(self.text)
        }
    }
}

struct ContentView: View {
    var body: some View {
        ZStack {
            TestView(text: "bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla")
                .frame(width: 250)
                .background(Color.red)
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())
</code>```

How can I get around this?

答:
WARNING ⚠ : This is when Geomtery reader couldn't help with me with geometry and I started to bang my head against the wall

Here's what you can do:

```<code>struct ContentView: View {

    var text =  "bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla"
    var width : CGFloat = 250

    var height: CGFloat {
        var size : CGFloat
        let chars = self.width / 14  // assuming width of 1 character is 14 which is the case by default for Text view
        let lines = CGFloat(text.count) / chars
        size = CGFloat(14 * (lines + 1))
        return size
    }

    var body: some View {
        ZStack {
            TestView(text: text)
            .frame(width: width, height: height)
            .background(Color.red)
        }
    }
}
</code>```

Set the height of the TestView manually by using height as a computed property.

A background story on how I estimated default font height

Press shift + command + 4
Use the pointer and find the difference between the relative y positions

Body:
This is the layout I'm aiming for.

import SwiftUI
import PlaygroundSupport

struct TestView: View {

    let text: String

    var body: some View {
        Text(self.text)
    }
}

struct ContentView: View {
    var body: some View {
        ZStack {
            TestView(text: "bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla")
                .frame(width: 250)
                .background(Color.red)
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())

But I also want to use the GeometryReader and when I put the Text inside the GeometryReader it will take up the full height.

import SwiftUI
import PlaygroundSupport

struct TestView: View {

    let text: String

    var body: some View {
        GeometryReader { reader in
            Text(self.text)
        }
    }
}

struct ContentView: View {
    var body: some View {
        ZStack {
            TestView(text: "bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla")
                .frame(width: 250)
                .background(Color.red)
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())

How can I get around this?

Body:
WARNING ⚠ : This is when Geomtery reader couldn't help with me with geometry and I started to bang my head against the wall

Here's what you can do:

struct ContentView: View {

    var text =  "bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla"
    var width : CGFloat = 250

    var height: CGFloat {
        var size : CGFloat
        let chars = self.width / 14  // assuming width of 1 character is 14 which is the case by default for Text view
        let lines = CGFloat(text.count) / chars
        size = CGFloat(14 * (lines + 1))
        return size
    }

    var body: some View {
        ZStack {
            TestView(text: text)
            .frame(width: width, height: height)
            .background(Color.red)
        }
    }
}

Set the height of the TestView manually by using height as a computed property.

A background story on how I estimated default font height

Press shift + command + 4
Use the pointer and find the difference between the relative y positions


问:
How do I add Pull to Refresh in WebView?
I'm very new to developing. I'm building a WebView and I want it to have pull to refresh capabilities. How do I go about doing that in swift?

My code in the View Controller is

```<code>@IBOutlet var webView: UIWebView!

override func viewDidLoad() {
    super.viewDidLoad()

    func webViewDidFinishLoad(webView: UIWebView) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    }

    func webViewDidStartLoad(webView: UIWebView) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    }

    let url = NSURL (string: "https://www.foo.com");
    let requestObj = NSURLRequest(URL: url!);
    webView.loadRequest(requestObj);
    NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"])
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}
</code>```

答:
Details

Xcode 11.3.1, Swift 5.1

Solution

```<code>extension WKWebView {

    var refreshControl: UIRefreshControl? { (scrollView.getAllSubviews() as [UIRefreshControl]).first }

    enum PullToRefreshType {
        case none
        case embed
        case custom(target: Any, selector: Selector)
    }

    func setPullToRefresh(type: PullToRefreshType) {
        (scrollView.getAllSubviews() as [UIRefreshControl]).forEach { $0.removeFromSuperview() }
        switch type {
            case .none: break
            case .embed: _setPullToRefresh(target: self, selector: #selector(webViewPullToRefreshHandler(source:)))
            case .custom(let params): _setPullToRefresh(target: params.target, selector: params.selector)
        }
    }

    private func _setPullToRefresh(target: Any, selector: Selector) {
        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(target, action: selector, for: .valueChanged)
        scrollView.addSubview(refreshControl)
    }

    @objc func webViewPullToRefreshHandler(source: UIRefreshControl) {
        guard let url = self.url else { source.endRefreshing(); return }
        load(URLRequest(url: url))
    }
}

// https://stackoverflow.com/a/47282118/4488252

extension UIView {

    class func getAllSubviews<T: UIView>(from parenView: UIView) -> [T] {
        return parenView.subviews.flatMap { subView -> [T] in
            var result = getAllSubviews(from: subView) as [T]
            if let view = subView as? T { result.append(view) }
            return result
        }
    }

    func getAllSubviews<T: UIView>() -> [T] { return UIView.getAllSubviews(from: self) as [T] }
}
</code>```

Usage

Setup

```<code>import UIKit
import WebKit

class ViewController2: UIViewController {
    private weak var webView: WKWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // ... create webView here
        webView.navigationDelegate = self
    }
}

// MARK: WKNavigationDelegate

extension ViewController2: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }
}
</code>```

Activate pull to refresh (option 1)

```<code> webView.setPullToRefresh(type: .embed)
</code>```

Activate pull to refresh (option 2)

```<code> @objc func customPullToRefreshHandler(source: UIRefreshControl) {
     guard let url = webView.url else { source.endRefreshing(); return }
     webView.load(URLRequest(url: url))
 }

 // ....

 webView.setPullToRefresh(type: .custom(target: self, selector: #selector(customPullToRefreshHandler(source:))))
</code>```

Deactivate pull to refresh

```<code> webView.setPullToRefresh(type: .none)
</code>```

Full sample

Do not forget to paste here the solution code

```<code>import UIKit
import WebKit

class ViewController: UIViewController {

    private weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        createWebView()
        webView.load("https://google.com")

        // Way 1
        webView.setPullToRefresh(type: .embed)

        // Way 2
       // webView.setPullToRefresh(type: .custom(target: self, selector: #selector(customPullToRefreshHandler(source:))))
    }

    private func createWebView() {
        let webView = WKWebView(frame: .zero, configuration: .init())
        view.addSubview(webView)
        webView.navigationDelegate = self
        self.webView = webView
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        webView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        view.bottomAnchor.constraint(equalTo: webView.bottomAnchor).isActive = true
        view.rightAnchor.constraint(equalTo: webView.rightAnchor).isActive = true
    }

//    @objc func customPullToRefreshHandler(source: UIRefreshControl) {
//        guard let url = webView.url else { source.endRefreshing(); return }
//        webView.load(URLRequest(url: url))
//        print("WebView started loading")
//    }
}

// MARK: WKNavigationDelegate

extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }
}

extension WKWebView {
    func load(_ urlString: String) {
        guard let url = URL(string: urlString) else { return }
        load(URLRequest(url: url))
    }
}
</code>```

Body:
I'm very new to developing. I'm building a WebView and I want it to have pull to refresh capabilities. How do I go about doing that in swift?

My code in the View Controller is

@IBOutlet var webView: UIWebView!

override func viewDidLoad() {
    super.viewDidLoad()

    func webViewDidFinishLoad(webView: UIWebView) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = false
    }

    func webViewDidStartLoad(webView: UIWebView) {
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    }

    let url = NSURL (string: "https://www.foo.com");
    let requestObj = NSURLRequest(URL: url!);
    webView.loadRequest(requestObj);
    NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"])
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

Body:
Details

Xcode 11.3.1, Swift 5.1

Solution

extension WKWebView {

    var refreshControl: UIRefreshControl? { (scrollView.getAllSubviews() as [UIRefreshControl]).first }

    enum PullToRefreshType {
        case none
        case embed
        case custom(target: Any, selector: Selector)
    }

    func setPullToRefresh(type: PullToRefreshType) {
        (scrollView.getAllSubviews() as [UIRefreshControl]).forEach { $0.removeFromSuperview() }
        switch type {
            case .none: break
            case .embed: _setPullToRefresh(target: self, selector: #selector(webViewPullToRefreshHandler(source:)))
            case .custom(let params): _setPullToRefresh(target: params.target, selector: params.selector)
        }
    }

    private func _setPullToRefresh(target: Any, selector: Selector) {
        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(target, action: selector, for: .valueChanged)
        scrollView.addSubview(refreshControl)
    }

    @objc func webViewPullToRefreshHandler(source: UIRefreshControl) {
        guard let url = self.url else { source.endRefreshing(); return }
        load(URLRequest(url: url))
    }
}

// https://stackoverflow.com/a/47282118/4488252

extension UIView {

    class func getAllSubviews<T: UIView>(from parenView: UIView) -> [T] {
        return parenView.subviews.flatMap { subView -> [T] in
            var result = getAllSubviews(from: subView) as [T]
            if let view = subView as? T { result.append(view) }
            return result
        }
    }

    func getAllSubviews<T: UIView>() -> [T] { return UIView.getAllSubviews(from: self) as [T] }
}

Usage

Setup

import UIKit
import WebKit

class ViewController2: UIViewController {
    private weak var webView: WKWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // ... create webView here
        webView.navigationDelegate = self
    }
}

// MARK: WKNavigationDelegate

extension ViewController2: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }
}

Activate pull to refresh (option 1)

 webView.setPullToRefresh(type: .embed)

Activate pull to refresh (option 2)

 @objc func customPullToRefreshHandler(source: UIRefreshControl) {
     guard let url = webView.url else { source.endRefreshing(); return }
     webView.load(URLRequest(url: url))
 }

 // ....

 webView.setPullToRefresh(type: .custom(target: self, selector: #selector(customPullToRefreshHandler(source:))))

Deactivate pull to refresh

 webView.setPullToRefresh(type: .none)

Full sample

Do not forget to paste here the solution code

import UIKit
import WebKit

class ViewController: UIViewController {

    private weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        createWebView()
        webView.load("https://google.com")

        // Way 1
        webView.setPullToRefresh(type: .embed)

        // Way 2
       // webView.setPullToRefresh(type: .custom(target: self, selector: #selector(customPullToRefreshHandler(source:))))
    }

    private func createWebView() {
        let webView = WKWebView(frame: .zero, configuration: .init())
        view.addSubview(webView)
        webView.navigationDelegate = self
        self.webView = webView
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        webView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        view.bottomAnchor.constraint(equalTo: webView.bottomAnchor).isActive = true
        view.rightAnchor.constraint(equalTo: webView.rightAnchor).isActive = true
    }

//    @objc func customPullToRefreshHandler(source: UIRefreshControl) {
//        guard let url = webView.url else { source.endRefreshing(); return }
//        webView.load(URLRequest(url: url))
//        print("WebView started loading")
//    }
}

// MARK: WKNavigationDelegate

extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        webView.refreshControl?.endRefreshing()
    }
}

extension WKWebView {
    func load(_ urlString: String) {
        guard let url = URL(string: urlString) else { return }
        load(URLRequest(url: url))
    }
}


问:
RecyclerView is always above other views
It seems to me that I have read all the topics on stackoverflow and have not found a solution.

The problem is that ImageView is always under RecyclerView, whatever I do, but I need to display ImageView on top of RecyclerView.

Question: Why is this happening and how can I fix it?

Example of right and wrong:

My XML:

```<code><androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:clickable="true"
 android:focusable="true"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 android:background="@drawable/bottom_style"
 android:overScrollMode="never"
 app:behavior_hideable="false"
 app:behavior_peekHeight="150dp"
 app:layout_behavior="....BottomSheetController.MyBottomSheetBehavior">

 <androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_marginTop="6dp"
    android:layout_marginBottom="6dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp">

        <....BottomSheetController.MyRecyclerView
            android:id="@+id/recycler_view"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:overScrollMode="never" />

        <ImageView
            android:id="@+id/close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_button_close" />
    </RelativeLayout>
 </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.core.widget.NestedScrollView>
</code>```

答:
Is there any specific reason why you need to wrap the content in RelativeLayout if not making use of a FrameLayout should fix your issue, remember to set android:layout_gravity="end|top" to position your close button on top-end. So the code looks something like below:

```<code><androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:clickable="true"
    android:focusable="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/bottom_style"
    android:overScrollMode="never"
    app:behavior_hideable="false"
    app:behavior_peekHeight="150dp"
    app:layout_behavior="....BottomSheetController.MyBottomSheetBehavior">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_marginTop="6dp"
        android:layout_marginBottom="6dp">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp">

            <....BottomSheetController.MyRecyclerView
            android:id="@+id/recycler_view"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:overScrollMode="never" />

            <ImageView
                android:id="@+id/close"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="end|top"
                android:src="@drawable/ic_button_close" />
        </FrameLayout>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.core.widget.NestedScrollView>
</code>```

As for the reason, from what I believe, why RelativeLayout was showing the incorrect output was because the  the distance of views on z-axis is set based on the order they are generated. So even though the ImageView is set after recyclerview, to be on the Top, but the holders inside are generated afterwards and are therefore on top of the imageview.
If it was a simple view generated before the imageview, image would be on top as desired.

P.S.: I didn't find any documentation for this and is purely how I believe it works so if that is not the case anyone is free to correct me.

Body:
It seems to me that I have read all the topics on stackoverflow and have not found a solution.

The problem is that ImageView is always under RecyclerView, whatever I do, but I need to display ImageView on top of RecyclerView.

Question: Why is this happening and how can I fix it?

Example of right and wrong:

My XML:

<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:clickable="true"
 android:focusable="true"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 android:background="@drawable/bottom_style"
 android:overScrollMode="never"
 app:behavior_hideable="false"
 app:behavior_peekHeight="150dp"
 app:layout_behavior="....BottomSheetController.MyBottomSheetBehavior">

 <androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_marginTop="6dp"
    android:layout_marginBottom="6dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp">

        <....BottomSheetController.MyRecyclerView
            android:id="@+id/recycler_view"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:overScrollMode="never" />

        <ImageView
            android:id="@+id/close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_button_close" />
    </RelativeLayout>
 </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.core.widget.NestedScrollView>

Body:
Is there any specific reason why you need to wrap the content in RelativeLayout if not making use of a FrameLayout should fix your issue, remember to set android:layout_gravity="end|top" to position your close button on top-end. So the code looks something like below:

<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:clickable="true"
    android:focusable="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/bottom_style"
    android:overScrollMode="never"
    app:behavior_hideable="false"
    app:behavior_peekHeight="150dp"
    app:layout_behavior="....BottomSheetController.MyBottomSheetBehavior">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_marginTop="6dp"
        android:layout_marginBottom="6dp">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp">

            <....BottomSheetController.MyRecyclerView
            android:id="@+id/recycler_view"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:overScrollMode="never" />

            <ImageView
                android:id="@+id/close"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="end|top"
                android:src="@drawable/ic_button_close" />
        </FrameLayout>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.core.widget.NestedScrollView>

As for the reason, from what I believe, why RelativeLayout was showing the incorrect output was because the  the distance of views on z-axis is set based on the order they are generated. So even though the ImageView is set after recyclerview, to be on the Top, but the holders inside are generated afterwards and are therefore on top of the imageview.
If it was a simple view generated before the imageview, image would be on top as desired.

P.S.: I didn't find any documentation for this and is purely how I believe it works so if that is not the case anyone is free to correct me.


问:
StringWriter or StringBuilder
What is the difference between StringWriter and StringBuilder and when should I use one or the other?

答:
StringWriter derives from TextWriter, which allows various classes to write text without caring where it's going. In the case of StringWriter, the output is just into memory. You would use this if you're calling an API which needs a TextWriter but you only want to build up results in memory.

StringBuilder is essentially a buffer which allows you to perform multiple operations (typically appends) to a "logical string" without creating a new string object each time. You would use this to construct a string in multiple operations.

OwnerDisplayName: MAC

Title: StringWriter or StringBuilder

OwnerDisplayName: Jon Skeet


问:
Packaging python project with multiple directories
I need some explanation on working with setuptools and find_packages function.
I have a project structure like this:

```<code>├── project_dir_1
│   ├── module.py
│   ├── __init__.py
├── my_project
│   ├── cli.py
│   ├── subdir1
│   │   ├── __init__.py
│   │   ├── module.py
│   ├── conf
│   │   ├── module.py
│   │   ├── params
│   │   │   ├── config.yml
│   │   ├── __init__.py
│   ├── subdir2
│   │   ├── module.py
│   ├── __init__.py
│   └── version.py
├── project_dir_2
│   ├──  subdir1
│   │   ├── module.py
│   │   ├── __init__.py
│   ├── __init__.py
├── README.md
├── requirements.txt
├── setup.py
└── tests
    └── test_main.py
</code>```

Actually all my code in the my_project dir and I also have two additonal dirs project_dir_1 and project_dir_2 that contains necessary external modules from where I should do imports both in the package code and in another projects code where this package will be installed in venv.
I have setup script like this:

```<code>setup(
    name='my_project',
    version='0.0.1',
    description='Python library.',
    license='license',
    author='me',
    author_email='my_email',
    entry_points={'console_scripts': ['my_project=my_project.cli:main']},
    python_requires='>=3.7',
    packages=find_packages(
        include=['my_project', 'project_dir_1', 'project_dir_2', 'my_project.*', 'project_dir_1.*', 'project_dir_2.*']
    ),
    install_requires=list(open(join(dirname(__file__), 'requirements.txt')).read().split()),
)
</code>```

When I activate venv in another project folder and trying to install package from package root folder like python ..\package_root\setup.py install everything seems to works fine during install. And pip list shows all dependencies and my_project 0.0.1. But if I'm trying to import something from my_project using the venv interpreter I got an error: ModuleNotFoundError: No module named 'my_project'. The same result if I'm trying to import something like from project_dir_1 import module which is also necessary. Also when I just run my_project from shell addressing to cli I got an error:

```<code>Traceback (most recent call last):
  File "/home/developer/another_project/env/bin/my_project", line 11, in <module>
    load_entry_point('my_project==0.0.1', 'console_scripts', 'my_project')()
  File "/home/developer/another_project/env/lib/python3.8/site-packages/pkg_resources/__init__.py", line 489, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/home/developer/another_project/env/lib/python3.8/site-packages/pkg_resources/__init__.py", line 2852, in load_entry_point
    return ep.load()
  File "/home/developer/another_project/env/lib/python3.8/site-packages/pkg_resources/__init__.py", line 2443, in load
    return self.resolve()
  File "/home/developer/another_project/env/lib/python3.8/site-packages/pkg_resources/__init__.py", line 2449, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
ModuleNotFoundError: No module named 'my_project'
</code>```

So what is the right way to organize this complex project structure and include all necessary code in setup.py to get the setuptools install the package correctly? I need some better understanding of python projects packaging but still don't get an answers for this case from seeking the docs.

答:
find_packages will resolve paths relative to current working directory, so calling it outside of the project root dir will effectively install nothing (check whether you see any sources installed by e.g. running

```<code>$ pip show -f my_project
</code>```

, I bet nothing will be listed). You have to force switching to the project root dir in the setup script, e.g. add a magic line to your setup script:

```<code># setup.py

import os
from setuptools import setup

# old-style for python 2
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))

# new style for python 3
from pathlib import Path
os.chdir(Path(__file__).parent.absolute())

setup(...)
</code>```

Body:
I need some explanation on working with setuptools and find_packages function.
I have a project structure like this:

├── project_dir_1
│   ├── module.py
│   ├── __init__.py
├── my_project
│   ├── cli.py
│   ├── subdir1
│   │   ├── __init__.py
│   │   ├── module.py
│   ├── conf
│   │   ├── module.py
│   │   ├── params
│   │   │   ├── config.yml
│   │   ├── __init__.py
│   ├── subdir2
│   │   ├── module.py
│   ├── __init__.py
│   └── version.py
├── project_dir_2
│   ├──  subdir1
│   │   ├── module.py
│   │   ├── __init__.py
│   ├── __init__.py
├── README.md
├── requirements.txt
├── setup.py
└── tests
    └── test_main.py

Actually all my code in the my_project dir and I also have two additonal dirs project_dir_1 and project_dir_2 that contains necessary external modules from where I should do imports both in the package code and in another projects code where this package will be installed in venv.
I have setup script like this:

setup(
    name='my_project',
    version='0.0.1',
    description='Python library.',
    license='license',
    author='me',
    author_email='my_email',
    entry_points={'console_scripts': ['my_project=my_project.cli:main']},
    python_requires='>=3.7',
    packages=find_packages(
        include=['my_project', 'project_dir_1', 'project_dir_2', 'my_project.*', 'project_dir_1.*', 'project_dir_2.*']
    ),
    install_requires=list(open(join(dirname(__file__), 'requirements.txt')).read().split()),
)

When I activate venv in another project folder and trying to install package from package root folder like python ..\package_root\setup.py install everything seems to works fine during install. And pip list shows all dependencies and my_project 0.0.1. But if I'm trying to import something from my_project using the venv interpreter I got an error: ModuleNotFoundError: No module named 'my_project'. The same result if I'm trying to import something like from project_dir_1 import module which is also necessary. Also when I just run my_project from shell addressing to cli I got an error:

Traceback (most recent call last):
  File "/home/developer/another_project/env/bin/my_project", line 11, in <module>
    load_entry_point('my_project==0.0.1', 'console_scripts', 'my_project')()
  File "/home/developer/another_project/env/lib/python3.8/site-packages/pkg_resources/__init__.py", line 489, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/home/developer/another_project/env/lib/python3.8/site-packages/pkg_resources/__init__.py", line 2852, in load_entry_point
    return ep.load()
  File "/home/developer/another_project/env/lib/python3.8/site-packages/pkg_resources/__init__.py", line 2443, in load
    return self.resolve()
  File "/home/developer/another_project/env/lib/python3.8/site-packages/pkg_resources/__init__.py", line 2449, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
ModuleNotFoundError: No module named 'my_project'

So what is the right way to organize this complex project structure and include all necessary code in setup.py to get the setuptools install the package correctly? I need some better understanding of python projects packaging but still don't get an answers for this case from seeking the docs.

Body:
find_packages will resolve paths relative to current working directory, so calling it outside of the project root dir will effectively install nothing (check whether you see any sources installed by e.g. running

$ pip show -f my_project

, I bet nothing will be listed). You have to force switching to the project root dir in the setup script, e.g. add a magic line to your setup script:

# setup.py

import os
from setuptools import setup

# old-style for python 2
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))

# new style for python 3
from pathlib import Path
os.chdir(Path(__file__).parent.absolute())

setup(...)


问:
How to ssh to a wordpress site
I'm having trouble logging into my wordpress wp-admin page. When I go to http://example.com/wp-admin it redirects to a secure https https://example.com/wp-admin.php and says "Web page not available".

Wordpress is hosting the site, so I can't FTP into it. Trying to SSH into it using my Wordpress username and password isn't working either.

```<code>ssh user@example.com
password: Password
</code>```

Results in: "Permission denied, please try again." Any help is appreciated.

答:
No SSH access, nor FTP, but if you just need to fiddle with files, how about using SFTP?

As per WordPress.com Support, SFTP access is available to Administrators of sites on WordPress.com's Business and eCommerce plans.

If you are on one of the other plans, and want SFTP access, you can upgrade your site from your plans page.

Title: How to ssh to a wordpress site

Body:
I'm having trouble logging into my wordpress wp-admin page. When I go to http://example.com/wp-admin it redirects to a secure https https://example.com/wp-admin.php and says "Web page not available".

Wordpress is hosting the site, so I can't FTP into it. Trying to SSH into it using my Wordpress username and password isn't working either.

ssh user@example.com
password: Password

Results in: "Permission denied, please try again." Any help is appreciated.


问:
Changing the formatting of a datetime.time axis in matplotlib
I am trying to change the formatting of the x-axis into %H:%M, while the xticklabel all became 00:00. The xs looks like follows:

```<code>[datetime.time(15, 8, 35), datetime.time(15, 8, 36), datetime.time(15, 8, 37)]
</code>```

I tried with the following script:

```<code>import matplotlib.dates as mdate
import matplotlib.pyplot as plt

dates = ['15:08:35', '15:08:36', '15:08:37']
xs = [datetime.strptime(d, '%H:%M:%S').time() for d in dates]
ys = range(len(xs))

plt.gca().xaxis.set_major_formatter(mdate.DateFormatter('%H:%M'))
plt.gca().xaxis.set_major_locator(mdate.DayLocator())

# Plot
plt.plot(xs, ys)
plt.gcf().autofmt_xdate()
plt.show()
</code>```

And the image looks like this:
Please click

How could I change xticklabel into my desired formatting?

答:
Matplotlib can handle datetime-objects easier than time objects. You can remove .time(). This code should work, I edited the dates to show changing x-values on the axis.

import matplotlib.dates as mdate
import matplotlib.pyplot as plt
from datetime import datetime, timedelta

dates = ["15:05:35", "16:08:36", "17:09:37"]
# remove .time() from strptime
xs = [datetime.strptime(d, "%H:%M:%S") for d in dates]

ys = range(len(xs))

plt.gca().xaxis.set_major_formatter(mdate.DateFormatter("%H:%M"))
plt.gca().xaxis.set_major_locator(mdate.DayLocator())

# show all x-values on the x-axis
plt.xticks(xs)
# Plot
plt.plot(xs, ys)

plt.show()
```

Body:
I am trying to change the formatting of the x-axis into %H:%M, while the xticklabel all became 00:00. The xs looks like follows:

[datetime.time(15, 8, 35), datetime.time(15, 8, 36), datetime.time(15, 8, 37)]

I tried with the following script:

import matplotlib.dates as mdate
import matplotlib.pyplot as plt

dates = ['15:08:35', '15:08:36', '15:08:37']
xs = [datetime.strptime(d, '%H:%M:%S').time() for d in dates]
ys = range(len(xs))

plt.gca().xaxis.set_major_formatter(mdate.DateFormatter('%H:%M'))
plt.gca().xaxis.set_major_locator(mdate.DayLocator())

# Plot
plt.plot(xs, ys)
plt.gcf().autofmt_xdate()
plt.show()

And the image looks like this:
Please click

How could I change xticklabel into my desired formatting?


问:
Localhost : 404 not found
I am using XAMPP. and internal server of Django.
When I browse to localhost or 127.0.0.1, It shows
Not Found . HTTP Error 404. The requested resource is not found.

It sometimes works fine and other times pops up the error.

Moreover, when I browse to my project url, ie 127.0.0.1:8000/cc , the project url works fine.

Any ideas why is this happening?

答:
Many frameworks like Laravel , Django ,... run local web server that work on another port except 80.For example port 8000 is the most commen port that these local web servers use.

So when you run web servers that frameworks build them and type localhost:8000 it works well.But web server that xampp(apache) runs it has another port.In default it has 80 that it does not need to type it in url.And if you change port you should mention it in url.

**In brief:**web server in framework is different from web server in xampp . Check the port of each server and mention it in url when you use them.

Title: Localhost : 404 not found


问:
Python function that takes lists and elements and makes one list
Hopefully an example could illustrate this better. I am creating a function that will take either a list of names, various lists of names, just a name or multiple names (not in a list) and make one list of them all (without importing... non-native libraries? I am ignorant here but I mean I want to use only what's already available in python).

```<code>def make_one_list(entry1, entry2, entry3 ...):
   #regardless of what is entered (well.. it has to be list or element)
   #extract elements from list and combine with single elements and...
   return one_big_list_of_all_elements

>>>make_one_list(['John','Mark'],'Mike',['Kate','Ally'],'Shawn','Marina'...)
['John','Mark','Mike','Kate','Ally','Shawn','Marina',...]
</code>```

My pseudo-code is not set in stone, obviously. I think, eventually, some input checking might be in order but not very pythonic in nature to do that. I am simply doing this as a personal communication function for my office.

THANKS!!

答:
```<code>def flatten(x):
    if isinstance(x, list):
        tmp = []
        for i in x:
            tmp.extend(flatten(i))
        return tmp
    else:
        return [x]
</code>```

Test:

```<code>print(repr(flatten([[1, 2, 3], 4, [5], [6, [7, 8], 9]])))
print(repr(flatten(1)))
print(repr(flatten([2])))
</code>```

Output:

```<code>[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1]
[2]
</code>```

Fast, clean, works for any type of elements and any depth of nested lists.
Note usage of "extend" which avoids creating excessive intermediate results. This makes the function efficient even for large lists.

Body:
Hopefully an example could illustrate this better. I am creating a function that will take either a list of names, various lists of names, just a name or multiple names (not in a list) and make one list of them all (without importing... non-native libraries? I am ignorant here but I mean I want to use only what's already available in python).

def make_one_list(entry1, entry2, entry3 ...):
   #regardless of what is entered (well.. it has to be list or element)
   #extract elements from list and combine with single elements and...
   return one_big_list_of_all_elements

>>>make_one_list(['John','Mark'],'Mike',['Kate','Ally'],'Shawn','Marina'...)
['John','Mark','Mike','Kate','Ally','Shawn','Marina',...]

My pseudo-code is not set in stone, obviously. I think, eventually, some input checking might be in order but not very pythonic in nature to do that. I am simply doing this as a personal communication function for my office.

THANKS!!

Body:
def flatten(x):
    if isinstance(x, list):
        tmp = []
        for i in x:
            tmp.extend(flatten(i))
        return tmp
    else:
        return [x]

Test:

print(repr(flatten([[1, 2, 3], 4, [5], [6, [7, 8], 9]])))
print(repr(flatten(1)))
print(repr(flatten([2])))

Output:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1]
[2]

Fast, clean, works for any type of elements and any depth of nested lists.
Note usage of "extend" which avoids creating excessive intermediate results. This makes the function efficient even for large lists.


问:
Getting key with maximum value in dictionary?
I have a dictionary where keys are strings, and values are integers.

```<code>stats = {'a': 1, 'b': 3000, 'c': 0}
</code>```

How do I get the key with the maximum value? In this case, it is 'b'.

Is there a nicer approach than using an intermediate list with reversed key-value tuples?

```<code>inverse = [(value, key) for key, value in stats.items()]
print(max(inverse)[1])
</code>```

答:
You can use:

```<code>max(d, key=d.get)
# which is equivalent to
max(d, key=lambda k: d.get(k))
</code>```

To return the key-value pair use:

```<code>max(d.items(), key=lambda k: k[1])
</code>```

Body:
I have a dictionary where keys are strings, and values are integers.

stats = {'a': 1, 'b': 3000, 'c': 0}

How do I get the key with the maximum value? In this case, it is 'b'.

Is there a nicer approach than using an intermediate list with reversed key-value tuples?

inverse = [(value, key) for key, value in stats.items()]
print(max(inverse)[1])

Body:
You can use:

max(d, key=d.get)
# which is equivalent to
max(d, key=lambda k: d.get(k))

To return the key-value pair use:

max(d.items(), key=lambda k: k[1])


问:
How can I create a URL based on controller and action method in Spring MVC?
I am using Spring MVC 3.0

I have a guestbook.jsp page where I want to create a link that points to GuestBookController's login method.

This is a simple task that most web frameworks handle this (e.g grails does it with g:link tag) but I couldn't find any documentation on this in the official SpringMVC docs.

So I am scratching my head - Is this functionality in some tag library? Does the framework expose it? Do I have to extend the framework to get this to work?

Note, I am not taking about hardcoding the url (which is an obvious but weak solution) but rather generating it based on controller and action name.

UPDATE:
Spring MVC doesn't provide this functionality. There is a JIRA ticket though. You can vote here https://jira.springsource.org/browse/SPR-5779

答:
Spring MVC uses the standard JSTL tags in JSPs so:

```<code><c:url value="/guestBook.html" var="guestBookLink" />
<a href="${guestBookLink}">Guest Book</a>
</code>```

In your controller:

```<code>@RequestMapping(value = "/guestBook")
public String handleGuestBook() { ... }
</code>```

Body:
Spring MVC uses the standard JSTL tags in JSPs so:

<c:url value="/guestBook.html" var="guestBookLink" />
<a href="${guestBookLink}">Guest Book</a>

In your controller:

@RequestMapping(value = "/guestBook")
public String handleGuestBook() { ... }


问:
Find all lines where a value exists in one line
Here is my query

```<code>        select order_no, pkg_no, zone_no
        from T_DETAIL_ITEM a
        where order_no = 495
        order by order_no, pkg_no
</code>```

For a given package I have zone number = 0

What I need to do is return all the lines with the pkg_no = 1597. Because one where exists with a zero zone.

I tried a few different 'where exists' lines and it isn't working.

答:
Try to self join.
This way you can put your requirement in the second table "instance" but retrieve everything from that table matches based on another common field.</p>

```<code>select distinct a.order_no, a.pkg_no, a.zone_no
        from T_DETAIL_ITEM a
        join T_DETAIL_ITEM b on b.pkg_no = a.pkg_no
        where b.zone_no = 0
        order by a.order_no, a.pkg_no
</code>```

Body:
Here is my query

        select order_no, pkg_no, zone_no
        from T_DETAIL_ITEM a
        where order_no = 495
        order by order_no, pkg_no

For a given package I have zone number = 0

What I need to do is return all the lines with the pkg_no = 1597. Because one where exists with a zero zone.

I tried a few different 'where exists' lines and it isn't working.

Body:
Try to self join.
This way you can put your requirement in the second table "instance" but retrieve everything from that table matches based on another common field.

select distinct a.order_no, a.pkg_no, a.zone_no
        from T_DETAIL_ITEM a
        join T_DETAIL_ITEM b on b.pkg_no = a.pkg_no
        where b.zone_no = 0
        order by a.order_no, a.pkg_no


问:
Adding a clone of an object to a list in c# (prevent modification from outside)
I have an object like 'obj1' which I want to add to a list. I can add it by just list1.add(obj1) .Now once I update obj1, the object in my list is also updating! (I understand that I am dealing with references here)

My requirement demands modifying the obj1 and add it to the list again! Instead of having two different objects, I have only one, because for both of them, the reference is the same - obj1.

Is there any way I can modify this obj1 and add it to the list and still not lose the old one? Any workarounds would be extremely helpful!

Thanks in Advance!

答:
From what I've read from the C# 6.0 Cookbook, the best way to do this is to create your own ShallowClone and DeepClone interfaces, then implement them. The reason it's not suggested to use ICloneable is due to the confusion around whether or not ICloneable creates a DeepClone or a ShallowClone, so instead make your own interfaces if Microsoft's don't work.

ShallowClone is recreating the object with all it's properties having the same reference (two different objects referencing the same properties)

DeepClone is recreating the object with new properties.

To do the ShallowClone, the following works:

```<code>public ShallowClone ShallowCopy() => (ShallowClone)this.MemberwiseClone();
</code>```

And for the DeepClone:

```<code>public DeepClone DeepCopy()
{
 BinaryFormatter BF = new BinaryFormatter();
 MemoryStream memStream = new MemoryStream();
 BF.Serialize(memStream, this);
 memStream.Flush();
 memStream.Position = 0;
 return (DeepClone)BF.Deserialize(memStream);
}
</code>```

Stolen straight from the book, so all credit goes there. I just remember that this is the way it "should" be done in C#. There may still be a better way however, especially seen as we're at C# 8.0 now.

You can just write your own ShallowClone and DeepClone methods, and assign each property or create new properties, but this is tedious, hence why the above methods are so useful.

So the idea is you implement these interfaces on the objects you want to clone, and then use the methods.

I was thinking of making these extension methods instead, but it doesn't work. My idea was something like:

```<code>public static class CloningExtention
{
    public static T ShallowClone(this T obj) => (T)obj.MemberwiseClone(); // Doesn't work

    public static T DeepClone(this T obj)
    {
        BinaryFormatter BF = new BinaryFormatter();
        MemoryStream memStream = new MemoryStream();
        BF.Serialize(memStream, this);
        memStream.Flush();
        memStream.Position = 0;
        return (T)BF.Deserialize(memStream);
    };
}
</code>```

But MemberwiseClone is a protected method, so extension methods don't work. Why is it protected? I have no idea, but if I had to guess, it'd be because there is a very good reason why you shouldn't be cloning objects anywhere you like.

However, I still wanted to demonstrate it, so you know not to do it. If anyone knows why this method is protected, please let me know.

Body:
From what I've read from the C# 6.0 Cookbook, the best way to do this is to create your own ShallowClone and DeepClone interfaces, then implement them. The reason it's not suggested to use ICloneable is due to the confusion around whether or not ICloneable creates a DeepClone or a ShallowClone, so instead make your own interfaces if Microsoft's don't work.

ShallowClone is recreating the object with all it's properties having the same reference (two different objects referencing the same properties)

DeepClone is recreating the object with new properties.

To do the ShallowClone, the following works:

public ShallowClone ShallowCopy() => (ShallowClone)this.MemberwiseClone();

And for the DeepClone:

public DeepClone DeepCopy()
{
 BinaryFormatter BF = new BinaryFormatter();
 MemoryStream memStream = new MemoryStream();
 BF.Serialize(memStream, this);
 memStream.Flush();
 memStream.Position = 0;
 return (DeepClone)BF.Deserialize(memStream);
}

Stolen straight from the book, so all credit goes there. I just remember that this is the way it "should" be done in C#. There may still be a better way however, especially seen as we're at C# 8.0 now.

You can just write your own ShallowClone and DeepClone methods, and assign each property or create new properties, but this is tedious, hence why the above methods are so useful.

So the idea is you implement these interfaces on the objects you want to clone, and then use the methods.

I was thinking of making these extension methods instead, but it doesn't work. My idea was something like:

public static class CloningExtention
{
    public static T ShallowClone(this T obj) => (T)obj.MemberwiseClone(); // Doesn't work

    public static T DeepClone(this T obj)
    {
        BinaryFormatter BF = new BinaryFormatter();
        MemoryStream memStream = new MemoryStream();
        BF.Serialize(memStream, this);
        memStream.Flush();
        memStream.Position = 0;
        return (T)BF.Deserialize(memStream);
    };
}

But MemberwiseClone is a protected method, so extension methods don't work. Why is it protected? I have no idea, but if I had to guess, it'd be because there is a very good reason why you shouldn't be cloning objects anywhere you like.

However, I still wanted to demonstrate it, so you know not to do it. If anyone knows why this method is protected, please let me know.


问:
Path Sharing Violation Error when modifying existing pdf using iText7
I created a pdf in c# using Itext7 but I am unable to overwrite the pdf after adding the header to it, it gives path sharing violation error. I am also closing the document properly.

I create a Pdf first of at least 10 pages using this code:

```<code>           if(FileBrowser.Success)
           {
            PdfWriter writer = new PdfWriter(path);

            PdfDocument pdf = new PdfDocument(writer);

            Document document = new Document(pdf, size);

            PdfPage page1 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page2 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page3 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page4 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page5 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page6 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page7 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page8 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page9 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page10 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            document.Close();
           }
           Header();  //Calling Header Function
</code>```

Then I am using this function to Add Header

```<code> void Header()
    {

        PdfDocument pdfDoc = new PdfDocument(new PdfReader(path), new PdfWriter(path));

        Document document = new Document(pdfDoc);

        Rectangle pageSize;
        PdfCanvas canvas;
        int n = pdfDoc.GetNumberOfPages();
        for (int i = 1; i <= n; i++)
        {
            PdfPage page = pdfDoc.GetPage(i);
            pageSize = page.GetPageSize();

            canvas = new PdfCanvas(page);
            canvas.BeginText().SetFontAndSize(PdfFontFactory.CreateFont(FontConstants.HELVETICA), 7)
           .MoveText(pageSize.GetWidth() / 2 - 24, pageSize.GetHeight() - 10)
           .ShowText("Header Text")
           .EndText();

        }
        document.Close();

      }
</code>```

It gives me this error:

```<code>IOException: Sharing violation on path C:\Users\dell-pc\Desktop\ty1234.pdf
System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) (at <7ba07f088431485bb722f3b3373e87ee>:0)
System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode) (at <7ba07f088431485bb722f3b3373e87ee>:0)
(wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode)
iText.IO.Util.FileUtil.GetBufferedOutputStream (System.String filename) (at <57da1b8d8a184e278c732544ebe6412a>:0)
iText.Kernel.Pdf.PdfWriter..ctor (System.String filename, iText.Kernel.Pdf.WriterProperties properties) (at <3dc307d472b9422b8d3082a4addd20b6>:0)
iText.Kernel.Pdf.PdfWriter..ctor (System.String filename) (at <3dc307d472b9422b8d3082a4addd20b6>:0)
(wrapper remoting-invoke-with-check) iText.Kernel.Pdf.PdfWriter..ctor(string)
Panel.HeaderFooter () (at Assets/Scripts/Panel.cs:6253)
Panel+<ShowSaveDialogCoroutine>d__100.MoveNext () (at Assets/Scripts/Panel.cs:6244)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
</code>```

The pdf is created but when it calls Header() function it gives error of PdfDocument line instead of replacing the existing pdf.
Can anyone help me in fixing this issue?

答:
You're trying to create both a PdfReader and a PdfWriter working on the same file:

```<code>PdfDocument pdfDoc = new PdfDocument(new PdfReader(path), new PdfWriter(path));
</code>```

That cannot work; if constructed for a file, the PdfReader requires that file to remain the same for as long as it works with it but the PdfWriter immediately starts writing to it, truncating it.

If you want to replace the original file with an edited version of it, you should use a second file temporarily.

Alternatively, if a temporary file is not desired at all, you can read the file into memory (a byte[]) first, point the reader to that byte[] and the writer to the original file name. Or point the writer to a ByteArrayOutputStream and after editing write the contents of that to the file.

Body:
I created a pdf in c# using Itext7 but I am unable to overwrite the pdf after adding the header to it, it gives path sharing violation error. I am also closing the document properly.

I create a Pdf first of at least 10 pages using this code:

           if(FileBrowser.Success)
           {
            PdfWriter writer = new PdfWriter(path);

            PdfDocument pdf = new PdfDocument(writer);

            Document document = new Document(pdf, size);

            PdfPage page1 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page2 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page3 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page4 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page5 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page6 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page7 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page8 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page9 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            PdfPage page10 = pdf.AddNewPage();
            document.Add(new iText.Layout.Element.AreaBreak());
            //Add Content

            document.Close();
           }
           Header();  //Calling Header Function

Then I am using this function to Add Header

 void Header()
    {

        PdfDocument pdfDoc = new PdfDocument(new PdfReader(path), new PdfWriter(path));

        Document document = new Document(pdfDoc);

        Rectangle pageSize;
        PdfCanvas canvas;
        int n = pdfDoc.GetNumberOfPages();
        for (int i = 1; i <= n; i++)
        {
            PdfPage page = pdfDoc.GetPage(i);
            pageSize = page.GetPageSize();

            canvas = new PdfCanvas(page);
            canvas.BeginText().SetFontAndSize(PdfFontFactory.CreateFont(FontConstants.HELVETICA), 7)
           .MoveText(pageSize.GetWidth() / 2 - 24, pageSize.GetHeight() - 10)
           .ShowText("Header Text")
           .EndText();

        }
        document.Close();

      }

It gives me this error:

IOException: Sharing violation on path C:\Users\dell-pc\Desktop\ty1234.pdf
System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) (at <7ba07f088431485bb722f3b3373e87ee>:0)
System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode) (at <7ba07f088431485bb722f3b3373e87ee>:0)
(wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode)
iText.IO.Util.FileUtil.GetBufferedOutputStream (System.String filename) (at <57da1b8d8a184e278c732544ebe6412a>:0)
iText.Kernel.Pdf.PdfWriter..ctor (System.String filename, iText.Kernel.Pdf.WriterProperties properties) (at <3dc307d472b9422b8d3082a4addd20b6>:0)
iText.Kernel.Pdf.PdfWriter..ctor (System.String filename) (at <3dc307d472b9422b8d3082a4addd20b6>:0)
(wrapper remoting-invoke-with-check) iText.Kernel.Pdf.PdfWriter..ctor(string)
Panel.HeaderFooter () (at Assets/Scripts/Panel.cs:6253)
Panel+<ShowSaveDialogCoroutine>d__100.MoveNext () (at Assets/Scripts/Panel.cs:6244)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)

The pdf is created but when it calls Header() function it gives error of PdfDocument line instead of replacing the existing pdf.
Can anyone help me in fixing this issue?

Body:
You're trying to create both a PdfReader and a PdfWriter working on the same file:

PdfDocument pdfDoc = new PdfDocument(new PdfReader(path), new PdfWriter(path));

That cannot work; if constructed for a file, the PdfReader requires that file to remain the same for as long as it works with it but the PdfWriter immediately starts writing to it, truncating it.

If you want to replace the original file with an edited version of it, you should use a second file temporarily.

Alternatively, if a temporary file is not desired at all, you can read the file into memory (a byte[]) first, point the reader to that byte[] and the writer to the original file name. Or point the writer to a ByteArrayOutputStream and after editing write the contents of that to the file.