问:
Image stretch on Macbook / Safari, all screen sizes
The page with the issue:
https://www.fastforwardcomposites.com/foiling-luxury-catamaran-eagle-class

My client is experiencing stretched images on Safari or Mac OS/Macbook only. I can't test why or fix it because I do not own a Mac. Wondering if there is anything I can do that fits within my code to prevent image stretch WHILE keeping the aspect ratio of the pictures and scaling up and down correctly on all screen sizes. I have set the width to a %, and the height to "auto". The code in question is a little long because it is housed inside a big tabbed content area, but you can safely assume any images that I've styled to be responsive within the tabs are stretching poorly on Mac (you can ignore the gallery tab, that's working fine).

Is there any way to set the images to be responsive and snap down to fit the size of the container as the screen is resized on Safari without using set px values? Or is my only option to set the images to a specific PX height and width for every single possible screen size? I'd obviously like to avoid that, as the images are already responsive and resize quite nicely on all other browsers and OS. Thanks guys!

/* ======================================================================== *
 * * * * * * * * * * * * * * * * * * TABS * * * * * * * * * * * * * * * * * *
 ========================================================================== */

.tabs {
    position: relative;
    margin: 40px auto;
    width: 92%;
    max-width: 100%;
    overflow: hidden;
    padding-top: 10px;
    margin-bottom: 60px;
}
.tabs input {
    position: absolute;
    z-index: 1000;
    width: 12.4857142857%;
    height: 50px;
    left: 0;
    top: 0;
    opacity: 0;
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
    filter: alpha(opacity=0);
    cursor: pointer;
    margin: 0;
}
.tabs input#tab-2 {
    left: 12%;
}
.tabs input#tab-3 {
    left: 24%;
}
.tabs input#tab-4 {
    left: 36%;
}
.tabs input#tab-5 {
    left: 48%;
}
.tabs input#tab-6 {
    left: 60%;
}
.tabs input#tab-7 {
    left: 72%;
}
.tabs input#tab-8 {
    left: 84%;
}
.tabs label {
    background: #e1e1e1;
    color: #333;
    font-size: 14px;
    line-height: 50px;
    height: 56px;
    border-radius: 0;
    position: relative;
    top: 0;
    padding: 0 20px;
    float: left;
    display: block;
    width: 12.5%;
    letter-spacing: 1px;
    text-transform: uppercase;
    font-weight: bold;
    text-align: center;
    box-sizing: border-box;
    -webkit-transition: all 150ms ease 0s;
    transition: all 150ms ease 0s;
}
.tabs label:hover {
    cursor: pointer;
}
.tabs label:after {
    content: '';
    background: #d8d8d8;
    position: absolute;
    bottom: -2px;
    left: 0;
    width: 100%;
    height: 2px;
    display: block;
}
.tabs input:hover + label {
    background: #b9b9b9;
}
.tabs label:first-of-type {
    z-index: 4;
}
.tab-label-2 {
    z-index: 4;
}
.tab-label-3 {
    z-index: 3;
}
.tab-label-4 {
    z-index: 2;
}
.tabs input:checked + label {
    background: #f0f0f0;
    color: #1a1a1a;
    z-index: 7;
}
.clear-shadow {
    clear: both;
}
.content {
    height: auto;
    width: 100%;
    float: left;
    position: relative;
    z-index: 7;
    background: #f2f2f2;
    top: -10px;
    box-sizing: border-box;
}
.content div {
    position: relative;
    float: left;
    width: 0;
    height: 0;
    box-sizing: border-box;
    top: 0;
    left: 0;
    z-index: 1;
    opacity: 0;
    background: #f2f2f2;
}
.content .ec-container, .content .ec-container .gallery, .content .ec-container .gallery div {
    width: 100% !important;
    height: 100% !important;
    opacity: 1 !important;
    margin: 20px auto 0 auto;
}

.content div h2 {
    margin-top: 0;
}
.tabs .tab-selector-1:checked ~ .content .content-1,
.tabs .tab-selector-2:checked ~ .content .content-2,
.tabs .tab-selector-3:checked ~ .content .content-3,
.tabs .tab-selector-4:checked ~ .content .content-4,
.tabs .tab-selector-5:checked ~ .content .content-5,
.tabs .tab-selector-6:checked ~ .content .content-6,
.tabs .tab-selector-7:checked ~ .content .content-7,
.tabs .tab-selector-8:checked ~ .content .content-8 {
    z-index: 100;
    opacity: 1;
//width: 100% / $numberOfTabs;
    width: 100%;
    height: auto;
    width: 100%;
    height: auto;
    padding: 4.5%;
}
.content div h2 {
    text-align: left;
    color: #21bca9;
    font-size: 25px;
    text-transform: uppercase;
}
.content div p {
    font-size: 14px;
    line-height: 22px;
    text-align: left;
    margin: 0;
    color: #222;
}

.content-6 {
    background-image: url(https://www.lancewalker.life/images/specs/eagle-class-specs-image-4.jpg) !important;
        background-position: 5% 100% !important;
  background-repeat: no-repeat !important;
  background-size: cover !important;
}

.tabs-link {
    color: #777;
    text-decoration: underline !important;
}
.tabs-link:hover {
    color: #9e9e9e;
}

.tab-img-lg {
    display: flex;
    margin: 10px auto 60px auto;
    width: 100%;
}

.tab-img-vert {
    margin: 0 auto;
    display: flex;
    width: 32% !important;
    max-width: 32% !important;
    justify-content: space-around;
}

.tab-img-container {
    display: flex;
    width: 100% !important;
    flex-direction: row;
    height: unset!important;
    opacity: 1 !important;
    margin: 60px auto 0 auto;
    justify-content: center;
    flex-wrap: wrap;
}

.img-tabs-container {
    width: 100% !important;
    opacity: 1 !important;
    display: flex;
    height: unset !important;
    flex-wrap: wrap;
}

.tab-img-container-col {
    display: flex;
    width: 48% !important;
    height: unset!important;
    opacity: 1 !important;
    margin: 0 auto 0 auto;
    flex-direction: column;
}

.tabs ul li {
    font-size: 14px;
    line-height: 30px;
    text-align: left;
    margin: 0;
    color: #222;
}

.img-main-tabs {
 width: 100%;
}

.img-below-content-tabs-vert {
    max-width: 32% !important;
    margin: 10px auto;
    height: auto !important;
}

.img-below-content-tabs {
    max-width: 32% !important;
    margin: 10px auto;
    height: auto !important;
}

@media screen and (max-width: 999px) {
    .img-below-content-tabs-vert {
        display: none;
    }

    .img-below-content-tabs {
        display: none;
    }

    .img-tabs-container {
        display: none;
    }

    .img-below-content-tabs-mobile {
        display: flex;
        margin: 10px auto;
        height: auto;
    }
}

@media screen and (min-width: 1000px) {
    .img-below-content-tabs-mobile {
        display: none;
    }
}

@media screen and (max-width: 800px) {
    .gallery img {
        max-width: ~"calc(50% - 40px)";
        margin: 20px;
        transition: opacity 200ms;
        cursor: pointer;
    }

    .gallery-no-lb-2-items div {
        max-width: 90%;
        margin: 20px;
    }

    .asyncGallery__Dots {
        bottom: 15px;
    }

    .asyncGallery__Counter {
        right: 15px;
        bottom: 15px;
        font-size: 12px;
    }

    .asyncGallery__Item {
        width: 100%;
    }

    .asyncGallery__ItemImage img {
        max-height: none;
        max-width: 100%;
    }

    .asyncGallery__ItemDescription {
        padding: 0 20px;
    }

    .asyncGallery__Next,
    .asyncGallery__Prev {
        display: none;
    }

    .gallery {
        display: inline-flex;
    }

    .gallery div {
        max-width: 90%;
        margin: 10px auto;
    }

    .gallery div img {
        max-width: 100%;
        margin: 0 auto;
    }
}

/* ================================================================================= *
 * * * * * * * * * * * * * * * * * * MEDIA QUERIES * * * * * * * * * * * * * * * * * *
 =================================================================================== */

@media screen and (min-width: 768px) {
    .tabs input:checked + label {
        top: -2px;
    }
}
@media screen and (max-width: 767px) {
    .tabs label {
        font-size: 14px;
        line-height: 50px;
        height: 50px;
        display: flex;
        width: 100%;
    }
    .tabs input {
        display: flex;
        flex-direction: column;
        position: absolute;
        z-index: -999;
    }
    .tabs {
        width: 100%;
        margin-top: 0;
    }
    .tabs input#tab-2 {
        left: 0;
        display: flex;
    }
    .tabs input#tab-3 {
        left: 0;
        display: flex;

    }
    .tabs input#tab-4 {
        left: 0;
        display: flex;

    }
    .tabs input#tab-5 {
        left: 0;
        display: flex;

    }
    .tabs input#tab-6 {
        left: 0;
        display: flex;

    }
    .tabs input#tab-7 {
        left: 0;
        display: flex;
    }
    .content {
        top: 0;
    }
    .tab-img-lg {
        margin: 20px auto;
    }
    .tabs .tab-selector-1:checked~.content .content-1,
    .tabs .tab-selector-2:checked~.content .content-2,
    .tabs .tab-selector-3:checked~.content .content-3,
    .tabs .tab-selector-4:checked~.content .content-4,
    .tabs .tab-selector-5:checked~.content .content-5,
    .tabs .tab-selector-6:checked~.content .content-6,
    .tabs .tab-selector-7:checked~.content .content-7,
    .tabs .tab-selector-8:checked~.content .content-8 {
        padding: 40px 15px;
    }
    .tab-img-container-col {
        width: 100% !important;
    }
}

@media screen and (min-width: 1000px) and (max-width: 1599px) {
    .arrow-container {
        top: 70vh;
    }
    .gallery div {
        max-width: ~"calc(25% - 10px)";
        margin: 0 5px 0 5px;
    }
    .tab-img-sm {
        margin: 10px auto;
        width: 46.1% !important;
        max-width: 46.1% !important;
    }
}
@media screen and (max-width: 1200px) {
    .tabs-h2 {
        margin-top: 20px;
    }
    .tab-img-sm {
        width: 46% !important;
    }
    p {
        font-size: 17px !important;
        line-height: 1.9em;
    }
    h2 {
        font-size: 22px !important;
    }
    .content div p {
        font-size: 14px !important;
    }
}

@media screen and (min-width: 1001px) and (max-width: 1200px) {
.tabs label {
    font-size: 12px;
}
}

@media screen and (max-width: 1000px) {
.tabs label {
    font-size: 10px;
}
}

@media screen and (max-width: 766px) {
    .arrow-container {
        display: none;
    }
    .tabs p{
        line-height: 1.7em;
    }
    .panel {
        padding: 8%;
    }
    .tab-img-sm {
        width: 97% !important;
        max-width: 97% !important;
        display: flex;
    }
    .tab-img-vert {
        margin: 10px auto;
        width: 100% !important;
        max-width: 100% !important;
    }
}

@media only screen and (-webkit-min-device-pixel-ratio: 1) and (max-device-width: 1023px) and (min-device-width: 767px) {
    .arrow-container {
        display: none;
    }
    .gallery div {
        max-width: 30%;
        margin: 5px 10px;
    }
    label {
        padding: .9% 2.3%;
    }
    .panel {
        padding: 6%;
    }
    .tabs h3 {
        font-size: 14px;
    }
    .tabs p{
        line-height: 1.5em;
    }
    .tabs input {
        position: absolute;
        height: 45px;
        left: 0;
        top: 10px;
    }
    .tabs {
        width: 100%;
    }
    .tabs label {
        font-size: 13px;
        padding: 0 10px;
    }
    .tabs input#tab-2 {
        left: 14.3%;
    }
    .tabs input#tab-3 {
        left: 28.7%;

    }
    .tabs input#tab-4 {
        left: 43%;

    }
    .tabs input#tab-5 {
        left: 57.2%;
    }
    .tabs input#tab-6 {
        left: 71.3%;

    }
    .tabs input#tab-7 {
        left: 85.8%;
    }
    .tab-img-sm {
        width: 48% !important;
    }
}

@media only screen and (-webkit-min-device-pixel-ratio: 1) and (max-device-width: 1330px) and (min-device-width: 1024px) {
    .arrow-container {
        display: none;
    }
    .tabs h3 {
        font-size: 15px;
    }
    .tabs p{
        line-height: 1.7em;
    }
    .panels {
        min-height: 755px;
    }
    .gallery div {
        max-width: 31%;
        margin: 5px 10px;
    }
    label {
        padding: .9% 2.3%;
    }
    .panel {
        padding: 6%;
    }
    .tabs input {
        position: absolute;
    }
    .tabs {
        width: 100%;
    }
    .tabs label {
        font-size: 13px;
        padding: 0 10px;
    }
    .tabs input#tab-2 {
        left: 14.3%;
    }
    .tabs input#tab-3 {
        left: 28.7%;

    }
    .tabs input#tab-4 {
        left: 43%;

    }
    .tabs input#tab-5 {
        left: 57.2%;
    }
    .tabs input#tab-6 {
        left: 71.3%;

    }
    .tabs input#tab-7 {
        left: 85.8%;
    }
    .tabs input {
        top: 10px;
    }
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><section class="tabs">

    <input id="tab-1" type="radio" name="radio-set" class="tab-selector-1" checked="checked" />
    <label for="tab-1" class="tab-label-1">Overview</label>

    <input id="tab-2" type="radio" name="radio-set" class="tab-selector-2" />
    <label for="tab-2" class="tab-label-2">Design</label>

    <input id="tab-3" type="radio" name="radio-set" class="tab-selector-3"/>
    <label for="tab-3" class="tab-label-3">Build</label>

    <input id="tab-4" type="radio" name="radio-set" class="tab-selector-4"/>
    <label for="tab-4" class="tab-label-4">Interior</label>

    <input id="tab-5" type="radio" name="radio-set" class="tab-selector-5"/>
    <label for="tab-5" class="tab-label-5">Options</label>

    <input id="tab-6" type="radio" name="radio-set" class="tab-selector-6"/>
    <label for="tab-6" class="tab-label-6">Specs</label>

    <input id="tab-7" type="radio" name="radio-set" class="tab-selector-7"/>
    <label for="tab-7" class="tab-label-7">Hybrid Wing</label>

    <input id="tab-8" type="radio" name="radio-set" class="tab-selector-8"/>
    <label for="tab-8" class="tab-label-8">Gallery</label>

    <div class="content">
        <div class="content-1">
            <img class="img-main-tabs" src="http://www.lancewalker.life/images/tab-images/overview-lg-img3.jpg">
            <h2 class="h2-tabs" style="margin-top: 3rem;">BORN TO PLAY - BUILT TO RACE</h2>
            <p>It started with the simple vision of delivering the technology and performance of a competitive racing boat to the recreational sailor. The Eagle Class 53 was designed for cruising and racing in a range of
                conditions. Constructed of all-carbon and honeycomb core, this yacht is capable of safely reaching between 25-35 knots in light wind.</p>
            <p style="margin-bottom: 3rem; margin-top: 10px;">Whether you are looking for a dose of adrenaline racing around the blue waters of the Caribbean or an afternoon of ZEN sitting back in comfort in the open-air saloon, the Eagle Class 53 will take you there.</p>
            <div class="img-tabs-container">

                <img class="img-below-content-tabs" src="http://www.lancewalker.life/images/tab-images/eagle-class-overview-image-1.jpg">
                <img class="img-below-content-tabs" src="http://www.lancewalker.life/images/tab-images/eagle-class-overview-image-3.jpg">
                <img class="img-below-content-tabs" src="http://www.lancewalker.life/images/tab-images/eagle-class-overview-image-2.jpg">
            </div>
            <img class="img-below-content-tabs-mobile" src="http://www.lancewalker.life/images/tab-images/eagle-class-overview-image-1.jpg">
            <img class="img-below-content-tabs-mobile" src="http://www.lancewalker.life/images/tab-images/eagle-class-overview-image-3.jpg">
            <img class="img-below-content-tabs-mobile" src="http://www.lancewalker.life/images/tab-images/eagle-class-overview-image-2.jpg">
        </div>
        <div class="content-2">
            <img class="img-main-tabs" src="http://www.lancewalker.life/images/design/eagle-class-design-image-top-updated.jpg">
            <h2 style="margin-top: 3rem;">Form and Function Perfectly Balanced</h2>
            <p>Maintaining optimal performance</p>
            <p>The sweep of the sheer</p>
            <p style="margin: 10px 0">
                Key focus was placed on weight</p>
            <p style="margin-bottom: 3rem;">Bringing the Eagle Class series from design to the water is a team of international talent
                with decades of experience in design, naval architecture, composite boatbuilding, and foil engineering. This
                mosaic of talent has designed world-class racing boats for Oracle Racing, Luna Rossa, and Artemis Racing.</p>
            <div class="img-tabs-container">
                <img class="img-below-content-tabs" src="http://www.lancewalker.life/images/design/eagle-class-design-image-bottom-1.jpg">
                <img class="img-below-content-tabs" src="http://www.lancewalker.life/images/design/eagle-class-design-image-bottom-2.jpg">
                <img class="img-below-content-tabs" src="http://www.lancewalker.life/images/design/eagle-class-design-image-bottom-3.jpg">
            </div>
            <img class="img-below-content-tabs-mobile" src="http://www.lancewalker.life/images/design/eagle-class-design-image-bottom-1.jpg">
            <img class="img-below-content-tabs-mobile" src="http://www.lancewalker.life/images/design/eagle-class-design-image-bottom-2.jpg">
            <img class="img-below-content-tabs-mobile" src="http://www.lancewalker.life/images/design/eagle-class-design-image-bottom-3.jpg">
        </div>
        <div class="content-3">
            <img class="img-main-tabs" src="http://www.lancewalker.life/images/build/eagle-class-build-image-top.jpg">
            <h2 style="margin-top: 3rem;">Experience, Process, Quality</h2>
            <p>A highly-capable, world class catamaran – realized by an experienced, dedicated team.</p>
            <ul>
                <li>Designed by the celebrated naval architect Paul Bieker, veteran designer of multiple America’s Cup projects</li>
                <li>Built by Fast Forward Composites, in Bristol, Rhode Island, by a crew of accomplished boatbuilders and seasoned composite specialists</li>
                <li>Aerospace derived materials</li>
                <h2 style="margin-top: 30px;">Construction</h2>
                <li>Vacuum-bagged epoxy pre-preg carbon fiber skins over honeycomb and various core foams</li>
                <li>All carbon spars and rig</li>
                <li>High modulus carbon fiber rotating Hybrid Wing</li>
                <li>Pre-preg carbon C-Foils and T-rudders</li>
                <li>Assembled in our newly renovated, state-of-the art production facility. Using our strong supplier relationships, we are able to secure the best resins, adhesives and aerospace grade honeycomb core ensuring the highest quality build.</li>
            </ul>
        </div>
        <div class="content-4">
            <img class="img-main-tabs" src="https://www.lancewalker.life/images/interior/interior-main-img.jpg">
            <h2 class="tabs-h2" style="margin-top: 3rem;">Open air sophistication</h2>
            <p style="margin: 0 0 10px 0;">The Eagle Class 53 is unique in that it combines very lightweight structures with vast space on deck and great accommodations inside. Sail control lines are in the hardtop and are operated from the
                forward part of the deck, allowing a line-free area for guests. All the systems are contained in the same area, creating an ideal weight concentration and a clean interior.</p>
            <p style="margin: 0 0 10px 0;">The spacious and airy cabins in each hull have a full 6'5" of headroom. The five windows combined with a large hatch above each bunk provide ocean views, fantastic natural light, and ventilation.
                Each cabin includes a Barcelona-style chair for lounging, a generous closet, and a full-length double bed at 6'8". The wet room/heads have enough room for two people, with specialized features such as a
                custom carbon sink and lightweight Techma head. All interior components are ergonomically designed using modern and lightweight materials.</p>
            <p style="margin-bottom: 3rem;">The main saloon features a central entertainment island. The bar contains a sink, refrigerator and additional storage and can be customized to include an ice-maker and microwave.
                The island is flanked by bar stools and two luxurious leather settees.</p>
            <div class="img-tabs-container">
                <img class="img-below-content-tabs-vert" src="https://www.lancewalker.life/images/interior/interior-1-vert.jpg">
                <img class="img-below-content-tabs-vert" src="https://www.lancewalker.life/images/interior/interior-2-vert.jpg">
                <img class="img-below-content-tabs-vert" src="https://www.lancewalker.life/images/interior/interior-3-vert.jpg">
            </div>
            <img class="img-below-content-tabs-mobile" src="https://www.lancewalker.life/images/interior/interior-1-vert.jpg">
            <img class="img-below-content-tabs-mobile" src="https://www.lancewalker.life/images/interior/interior-2-vert.jpg">
            <img class="img-below-content-tabs-mobile" src="https://www.lancewalker.life/images/interior/interior-3-vert.jpg">
        </div>
        <div class="content-5">
            <img class="img-main-tabs" src="https://www.lancewalker.life/images/options/eagle-class-options-img-main.jpg">
            <h2 style="margin-top: 3rem;">Options</h2>
            <p style="margin-bottom: 3rem;">Owners have the choice of a variety of performance options, including the option of a standard rig or Hybrid Wing. The Eagle Class 53T is a turbo-charged version of the Eagle Class 53.
                Standard C-foils are replaced with carbon fiber T-foils creating a platform which foils at very low wind speeds and significantly increases the speed potential of the boat in medium to
                heavy wind conditions. The 53T also comes equipped with our fully automated foiling control system. The possibilities are endless.
            </p>

        </div>
        <div class="content-6">
            <div class="tab-img-container" style="margin-top: 0 !important; background: none !important;">
                <div class="tab-img-container-col" style="background: none !important;">
                        <h2>SPECS</h2>
                </div>
                <div class="tab-img-container-col" style="background: none !important;">
                </div>
            </div>
        </div>
        <div class="content-7">
            <!--<div class="tab-img-container">
                <img class="tab-img-sm" src="https://www.lancewalker.life/images/hybridwing/hw-brand-logo.jpg">
            </div>-->
            <h2>Hybrid-Wing</h2>
            <p>            </p><br>
            <div style="padding:56.25% 0 0 0;position:relative; opacity: 1; width: 100%; height: 100%;">
                <iframe src="https://player.vimeo.com/video/352449872?byline=0&portrait=0"
                        style="position:absolute;top:0;left:0;width:100%;height:100%;"
                        frameborder="0" allow="autoplay; fullscreen"
                        allowfullscreen></iframe></div>
            <script src="https://player.vimeo.com/api/player.js"></script>
        </div>
        <div class="content-8">
            <div class="ec-container" id="project-ec">
        </div>
    </div>
</section></code>```

答: Try experimenting with percent instead of PX  or a combination and position:absolute. Apply margins using percent etc. Might have to re-arrange things slightly but might work. Combinations also include using left and margin-left, for example, positive and negative.

Body:
The page with the issue:
https://www.fastforwardcomposites.com/foiling-luxury-catamaran-eagle-class

My client is experiencing stretched images on Safari or Mac OS/Macbook only. I can't test why or fix it because I do not own a Mac. Wondering if there is anything I can do that fits within my code to prevent image stretch WHILE keeping the aspect ratio of the pictures and scaling up and down correctly on all screen sizes. I have set the width to a %, and the height to "auto". The code in question is a little long because it is housed inside a big tabbed content area, but you can safely assume any images that I've styled to be responsive within the tabs are stretching poorly on Mac (you can ignore the gallery tab, that's working fine).

Is there any way to set the images to be responsive and snap down to fit the size of the container as the screen is resized on Safari without using set px values? Or is my only option to set the images to a specific PX height and width for every single possible screen size? I'd obviously like to avoid that, as the images are already responsive and resize quite nicely on all other browsers and OS. Thanks guys!

/* ======================================================================== *
 * * * * * * * * * * * * * * * * * * TABS * * * * * * * * * * * * * * * * * *
 ========================================================================== */

.tabs {
    position: relative;
    margin: 40px auto;
    width: 92%;
    max-width: 100%;
    overflow: hidden;
    padding-top: 10px;
    margin-bottom: 60px;
}
.tabs input {
    position: absolute;
    z-index: 1000;
    width: 12.4857142857%;
    height: 50px;
    left: 0;
    top: 0;
    opacity: 0;
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
    filter: alpha(opacity=0);
    cursor: pointer;
    margin: 0;
}
.tabs input#tab-2 {
    left: 12%;
}
.tabs input#tab-3 {
    left: 24%;
}
.tabs input#tab-4 {
    left: 36%;
}
.tabs input#tab-5 {
    left: 48%;
}
.tabs input#tab-6 {
    left: 60%;
}
.tabs input#tab-7 {
    left: 72%;
}
.tabs input#tab-8 {
    left: 84%;
}
.tabs label {
    background: #e1e1e1;
    color: #333;
    font-size: 14px;
    line-height: 50px;
    height: 56px;
    border-radius: 0;
    position: relative;
    top: 0;
    padding: 0 20px;
    float: left;
    display: block;
    width: 12.5%;
    letter-spacing: 1px;
    text-transform: uppercase;
    font-weight: bold;
    text-align: center;
    box-sizing: border-box;
    -webkit-transition: all 150ms ease 0s;
    transition: all 150ms ease 0s;
}
.tabs label:hover {
    cursor: pointer;
}
.tabs label:after {
    content: '';
    background: #d8d8d8;
    position: absolute;
    bottom: -2px;
    left: 0;
    width: 100%;
    height: 2px;
    display: block;
}
.tabs input:hover + label {
    background: #b9b9b9;
}
.tabs label:first-of-type {
    z-index: 4;
}
.tab-label-2 {
    z-index: 4;
}
.tab-label-3 {
    z-index: 3;
}
.tab-label-4 {
    z-index: 2;
}
.tabs input:checked + label {
    background: #f0f0f0;
    color: #1a1a1a;
    z-index: 7;
}
.clear-shadow {
    clear: both;
}
.content {
    height: auto;
    width: 100%;
    float: left;
    position: relative;
    z-index: 7;
    background: #f2f2f2;
    top: -10px;
    box-sizing: border-box;
}
.content div {
    position: relative;
    float: left;
    width: 0;
    height: 0;
    box-sizing: border-box;
    top: 0;
    left: 0;
    z-index: 1;
    opacity: 0;
    background: #f2f2f2;
}
.content .ec-container, .content .ec-container .gallery, .content .ec-container .gallery div {
    width: 100% !important;
    height: 100% !important;
    opacity: 1 !important;
    margin: 20px auto 0 auto;
}

.content div h2 {
    margin-top: 0;
}
.tabs .tab-selector-1:checked ~ .content .content-1,
.tabs .tab-selector-2:checked ~ .content .content-2,
.tabs .tab-selector-3:checked ~ .content .content-3,
.tabs .tab-selector-4:checked ~ .content .content-4,
.tabs .tab-selector-5:checked ~ .content .content-5,
.tabs .tab-selector-6:checked ~ .content .content-6,
.tabs .tab-selector-7:checked ~ .content .content-7,
.tabs .tab-selector-8:checked ~ .content .content-8 {
    z-index: 100;
    opacity: 1;
//width: 100% / $numberOfTabs;
    width: 100%;
    height: auto;
    width: 100%;
    height: auto;
    padding: 4.5%;
}
.content div h2 {
    text-align: left;
    color: #21bca9;
    font-size: 25px;
    text-transform: uppercase;
}
.content div p {
    font-size: 14px;
    line-height: 22px;
    text-align: left;
    margin: 0;
    color: #222;
}

.content-6 {
    background-image: url(https://www.lancewalker.life/images/specs/eagle-class-specs-image-4.jpg) !important;
        background-position: 5% 100% !important;
  background-repeat: no-repeat !important;
  background-size: cover !important;
}

.tabs-link {
    color: #777;
    text-decoration: underline !important;
}
.tabs-link:hover {
    color: #9e9e9e;
}

.tab-img-lg {
    display: flex;
    margin: 10px auto 60px auto;
    width: 100%;
}

.tab-img-vert {
    margin: 0 auto;
    display: flex;
    width: 32% !important;
    max-width: 32% !important;
    justify-content: space-around;
}

.tab-img-container {
    display: flex;
    width: 100% !important;
    flex-direction: row;
    height: unset!important;
    opacity: 1 !important;
    margin: 60px auto 0 auto;
    justify-content: center;
    flex-wrap: wrap;
}

.img-tabs-container {
    width: 100% !important;
    opacity: 1 !important;
    display: flex;
    height: unset !important;
    flex-wrap: wrap;
}

.tab-img-container-col {
    display: flex;
    width: 48% !important;
    height: unset!important;
    opacity: 1 !important;
    margin: 0 auto 0 auto;
    flex-direction: column;
}

.tabs ul li {
    font-size: 14px;
    line-height: 30px;
    text-align: left;
    margin: 0;
    color: #222;
}

.img-main-tabs {
 width: 100%;
}

.img-below-content-tabs-vert {
    max-width: 32% !important;
    margin: 10px auto;
    height: auto !important;
}

.img-below-content-tabs {
    max-width: 32% !important;
    margin: 10px auto;
    height: auto !important;
}

@media screen and (max-width: 999px) {
    .img-below-content-tabs-vert {
        display: none;
    }

    .img-below-content-tabs {
        display: none;
    }

    .img-tabs-container {
        display: none;
    }

    .img-below-content-tabs-mobile {
        display: flex;
        margin: 10px auto;
        height: auto;
    }
}

@media screen and (min-width: 1000px) {
    .img-below-content-tabs-mobile {
        display: none;
    }
}

@media screen and (max-width: 800px) {
    .gallery img {
        max-width: ~"calc(50% - 40px)";
        margin: 20px;
        transition: opacity 200ms;
        cursor: pointer;
    }

    .gallery-no-lb-2-items div {
        max-width: 90%;
        margin: 20px;
    }

    .asyncGallery__Dots {
        bottom: 15px;
    }

    .asyncGallery__Counter {
        right: 15px;
        bottom: 15px;
        font-size: 12px;
    }

    .asyncGallery__Item {
        width: 100%;
    }

    .asyncGallery__ItemImage img {
        max-height: none;
        max-width: 100%;
    }

    .asyncGallery__ItemDescription {
        padding: 0 20px;
    }

    .asyncGallery__Next,
    .asyncGallery__Prev {
        display: none;
    }

    .gallery {
        display: inline-flex;
    }

    .gallery div {
        max-width: 90%;
        margin: 10px auto;
    }

    .gallery div img {
        max-width: 100%;
        margin: 0 auto;
    }
}

/* ================================================================================= *
 * * * * * * * * * * * * * * * * * * MEDIA QUERIES * * * * * * * * * * * * * * * * * *
 =================================================================================== */

@media screen and (min-width: 768px) {
    .tabs input:checked + label {
        top: -2px;
    }
}
@media screen and (max-width: 767px) {
    .tabs label {
        font-size: 14px;
        line-height: 50px;
        height: 50px;
        display: flex;
        width: 100%;
    }
    .tabs input {
        display: flex;
        flex-direction: column;
        position: absolute;
        z-index: -999;
    }
    .tabs {
        width: 100%;
        margin-top: 0;
    }
    .tabs input#tab-2 {
        left: 0;
        display: flex;
    }
    .tabs input#tab-3 {
        left: 0;
        display: flex;

    }
    .tabs input#tab-4 {
        left: 0;
        display: flex;

    }
    .tabs input#tab-5 {
        left: 0;
        display: flex;

    }
    .tabs input#tab-6 {
        left: 0;
        display: flex;

    }
    .tabs input#tab-7 {
        left: 0;
        display: flex;
    }
    .content {
        top: 0;
    }
    .tab-img-lg {
        margin: 20px auto;
    }
    .tabs .tab-selector-1:checked~.content .content-1,
    .tabs .tab-selector-2:checked~.content .content-2,
    .tabs .tab-selector-3:checked~.content .content-3,
    .tabs .tab-selector-4:checked~.content .content-4,
    .tabs .tab-selector-5:checked~.content .content-5,
    .tabs .tab-selector-6:checked~.content .content-6,
    .tabs .tab-selector-7:checked~.content .content-7,
    .tabs .tab-selector-8:checked~.content .content-8 {
        padding: 40px 15px;
    }
    .tab-img-container-col {
        width: 100% !important;
    }
}

@media screen and (min-width: 1000px) and (max-width: 1599px) {
    .arrow-container {
        top: 70vh;
    }
    .gallery div {
        max-width: ~"calc(25% - 10px)";
        margin: 0 5px 0 5px;
    }
    .tab-img-sm {
        margin: 10px auto;
        width: 46.1% !important;
        max-width: 46.1% !important;
    }
}
@media screen and (max-width: 1200px) {
    .tabs-h2 {
        margin-top: 20px;
    }
    .tab-img-sm {
        width: 46% !important;
    }
    p {
        font-size: 17px !important;
        line-height: 1.9em;
    }
    h2 {
        font-size: 22px !important;
    }
    .content div p {
        font-size: 14px !important;
    }
}

@media screen and (min-width: 1001px) and (max-width: 1200px) {
.tabs label {
    font-size: 12px;
}
}

@media screen and (max-width: 1000px) {
.tabs label {
    font-size: 10px;
}
}

@media screen and (max-width: 766px) {
    .arrow-container {
        display: none;
    }
    .tabs p{
        line-height: 1.7em;
    }
    .panel {
        padding: 8%;
    }
    .tab-img-sm {
        width: 97% !important;
        max-width: 97% !important;
        display: flex;
    }
    .tab-img-vert {
        margin: 10px auto;
        width: 100% !important;
        max-width: 100% !important;
    }
}

@media only screen and (-webkit-min-device-pixel-ratio: 1) and (max-device-width: 1023px) and (min-device-width: 767px) {
    .arrow-container {
        display: none;
    }
    .gallery div {
        max-width: 30%;
        margin: 5px 10px;
    }
    label {
        padding: .9% 2.3%;
    }
    .panel {
        padding: 6%;
    }
    .tabs h3 {
        font-size: 14px;
    }
    .tabs p{
        line-height: 1.5em;
    }
    .tabs input {
        position: absolute;
        height: 45px;
        left: 0;
        top: 10px;
    }
    .tabs {
        width: 100%;
    }
    .tabs label {
        font-size: 13px;
        padding: 0 10px;
    }
    .tabs input#tab-2 {
        left: 14.3%;
    }
    .tabs input#tab-3 {
        left: 28.7%;

    }
    .tabs input#tab-4 {
        left: 43%;

    }
    .tabs input#tab-5 {
        left: 57.2%;
    }
    .tabs input#tab-6 {
        left: 71.3%;

    }
    .tabs input#tab-7 {
        left: 85.8%;
    }
    .tab-img-sm {
        width: 48% !important;
    }
}

@media only screen and (-webkit-min-device-pixel-ratio: 1) and (max-device-width: 1330px) and (min-device-width: 1024px) {
    .arrow-container {
        display: none;
    }
    .tabs h3 {
        font-size: 15px;
    }
    .tabs p{
        line-height: 1.7em;
    }
    .panels {
        min-height: 755px;
    }
    .gallery div {
        max-width: 31%;
        margin: 5px 10px;
    }
    label {
        padding: .9% 2.3%;
    }
    .panel {
        padding: 6%;
    }
    .tabs input {
        position: absolute;
    }
    .tabs {
        width: 100%;
    }
    .tabs label {
        font-size: 13px;
        padding: 0 10px;
    }
    .tabs input#tab-2 {
        left: 14.3%;
    }
    .tabs input#tab-3 {
        left: 28.7%;

    }
    .tabs input#tab-4 {
        left: 43%;

    }
    .tabs input#tab-5 {
        left: 57.2%;
    }
    .tabs input#tab-6 {
        left: 71.3%;

    }
    .tabs input#tab-7 {
        left: 85.8%;
    }
    .tabs input {
        top: 10px;
    }
}

    <input id="tab-1" type="radio" name="radio-set" class="tab-selector-1" checked="checked" />
    Overview

    <input id="tab-2" type="radio" name="radio-set" class="tab-selector-2" />
    Design

    <input id="tab-3" type="radio" name="radio-set" class="tab-selector-3"/>
    Build

    <input id="tab-4" type="radio" name="radio-set" class="tab-selector-4"/>
    Interior

    <input id="tab-5" type="radio" name="radio-set" class="tab-selector-5"/>
    Options

    <input id="tab-6" type="radio" name="radio-set" class="tab-selector-6"/>
    Specs

    <input id="tab-7" type="radio" name="radio-set" class="tab-selector-7"/>
    Hybrid Wing

    <input id="tab-8" type="radio" name="radio-set" class="tab-selector-8"/>
    Gallery

BORN TO PLAY - BUILT TO RACE

It started with the simple vision of delivering the technology and performance of a competitive racing boat to the recreational sailor. The Eagle Class 53 was designed for cruising and racing in a range of
                conditions. Constructed of all-carbon and honeycomb core, this yacht is capable of safely reaching between 25-35 knots in light wind.

Whether you are looking for a dose of adrenaline racing around the blue waters of the Caribbean or an afternoon of ZEN sitting back in comfort in the open-air saloon, the Eagle Class 53 will take you there.

Form and Function Perfectly Balanced

Maintaining optimal performance

The sweep of the sheer

                Key focus was placed on weight

Bringing the Eagle Class series from design to the water is a team of international talent
                with decades of experience in design, naval architecture, composite boatbuilding, and foil engineering. This
                mosaic of talent has designed world-class racing boats for Oracle Racing, Luna Rossa, and Artemis Racing.

Experience, Process, Quality

A highly-capable, world class catamaran – realized by an experienced, dedicated team.

Designed by the celebrated naval architect Paul Bieker, veteran designer of multiple America’s Cup projects

Built by Fast Forward Composites, in Bristol, Rhode Island, by a crew of accomplished boatbuilders and seasoned composite specialists

Aerospace derived materials

Construction

Vacuum-bagged epoxy pre-preg carbon fiber skins over honeycomb and various core foams

All carbon spars and rig

High modulus carbon fiber rotating Hybrid Wing

Pre-preg carbon C-Foils and T-rudders

Assembled in our newly renovated, state-of-the art production facility. Using our strong supplier relationships, we are able to secure the best resins, adhesives and aerospace grade honeycomb core ensuring the highest quality build.

Open air sophistication

The Eagle Class 53 is unique in that it combines very lightweight structures with vast space on deck and great accommodations inside. Sail control lines are in the hardtop and are operated from the
                forward part of the deck, allowing a line-free area for guests. All the systems are contained in the same area, creating an ideal weight concentration and a clean interior.

The spacious and airy cabins in each hull have a full 6'5" of headroom. The five windows combined with a large hatch above each bunk provide ocean views, fantastic natural light, and ventilation.
                Each cabin includes a Barcelona-style chair for lounging, a generous closet, and a full-length double bed at 6'8". The wet room/heads have enough room for two people, with specialized features such as a
                custom carbon sink and lightweight Techma head. All interior components are ergonomically designed using modern and lightweight materials.

The main saloon features a central entertainment island. The bar contains a sink, refrigerator and additional storage and can be customized to include an ice-maker and microwave.
                The island is flanked by bar stools and two luxurious leather settees.

Options

Owners have the choice of a variety of performance options, including the option of a standard rig or Hybrid Wing. The Eagle Class 53T is a turbo-charged version of the Eagle Class 53.
                Standard C-foils are replaced with carbon fiber T-foils creating a platform which foils at very low wind speeds and significantly increases the speed potential of the boat in medium to
                heavy wind conditions. The 53T also comes equipped with our fully automated foiling control system. The possibilities are endless.

SPECS

Hybrid-Wing


来源: stackexchange

问:
Why is the hostname declared invalid when creating a URI
Running this code with JDK 1.8:

```<code>try {
    System.out.println( new URI(null, null, "5-12-145-35_s-81", 443, null, null, null));
} catch (URISyntaxException e) {
    e.printStackTrace();
}
</code>```

results in this error: java.net.URISyntaxException: Illegal character in hostname at index 13: //5-12-145-35_s-81:443

Where does this error come from, considering all the hostname characters seem legit, according to Types of URI characters?

If I use these URLs: //5-12-145-35_s-81:443 or /5-12-145-35_s-81:443 the error is gone.

From the comments, I understand that, according to RFC-2396, the hostname cannot contain any underscore characters.

The question that still holds is why a hostname starting with slash or double slash is allowed to contain underscores?

答:
Underscores are not supported in URIs.

While a hostname may not contain other characters, such as the
  underscore character (_), other DNS names may contain the
  underscore.[5][6] This restriction was lifted by RFC 2181, Section 11.
  Systems such as DomainKeys and service records use the underscore as a
  means to assure that their special character is not confused with
  hostnames. For example, _http._sctp.www.example.com specifies a
  service pointer for an SCTP-capable webserver host (www) in the domain
  example.com. Notwithstanding the standard, Chrome, Firefox, Internet
  Explorer, Edge and Safari allow underscores in hostnames, although
  cookies in IE do not work correctly if any part of the hostname
  contains an underscore character

Wikipedia

From Javadocs :

public URI(String str) throws URISyntaxException Throws:
  URISyntaxException - If the given string violates RFC 2396, as
  augmented by the above deviations

Javadocs

(Hacky) Solution :

```<code>    URI url = URI.create("https://5-12-145-35_s-8:8080");

    System.out.println(url.getHost()) // null

    if (url.getHost() == null) {
        final Field hostField = URI.class.getDeclaredField("host");
        hostField.setAccessible(true);
        hostField.set(url, "5-12-145-35_s-81");
    }
    System.out.println(url.getHost()); // 5-12-145-35_s-81
</code>```

This was reported as  - JDK bug

ContentLicense: CC BY-SA 4.0

Body:
Running this code with JDK 1.8:

try {
    System.out.println( new URI(null, null, "5-12-145-35_s-81", 443, null, null, null));
} catch (URISyntaxException e) {
    e.printStackTrace();
}

results in this error: java.net.URISyntaxException: Illegal character in hostname at index 13: //5-12-145-35_s-81:443

Where does this error come from, considering all the hostname characters seem legit, according to Types of URI characters?

If I use these URLs: //5-12-145-35_s-81:443 or /5-12-145-35_s-81:443 the error is gone.

From the comments, I understand that, according to RFC-2396, the hostname cannot contain any underscore characters.

The question that still holds is why a hostname starting with slash or double slash is allowed to contain underscores?

Body:
Underscores are not supported in URIs.

While a hostname may not contain other characters, such as the
  underscore character (_), other DNS names may contain the
  underscore.[5][6] This restriction was lifted by RFC 2181, Section 11.
  Systems such as DomainKeys and service records use the underscore as a
  means to assure that their special character is not confused with
  hostnames. For example, _http._sctp.www.example.com specifies a
  service pointer for an SCTP-capable webserver host (www) in the domain
  example.com. Notwithstanding the standard, Chrome, Firefox, Internet
  Explorer, Edge and Safari allow underscores in hostnames, although
  cookies in IE do not work correctly if any part of the hostname
  contains an underscore character

Wikipedia

From Javadocs :

public URI(String str) throws URISyntaxException Throws:
  URISyntaxException - If the given string violates RFC 2396, as
  augmented by the above deviations

Javadocs

(Hacky) Solution :

    URI url = URI.create("https://5-12-145-35_s-8:8080");

    System.out.println(url.getHost()) // null

    if (url.getHost() == null) {
        final Field hostField = URI.class.getDeclaredField("host");
        hostField.setAccessible(true);
        hostField.set(url, "5-12-145-35_s-81");
    }
    System.out.println(url.getHost()); // 5-12-145-35_s-81

This was reported as  - JDK bug


问:
Why stm32nucleo board uart can't receive message after almost three or four hundred times using HAL_UART_Receive_IT
I am developing uart communication on STMicroelectronics NUCLEO-G474RE Board(stm32G474RETX MCU, 64pins) using MDK-v5, but run into a perplexing problem these several days, make no progress on it and have to reach out to seek some help. If anyone could give me a right way to go, it would be appreciated greatly.

Code is not complicated, I use cubeMX to initialize the code base with usart2 configured, and use two threads based on cmsis v2 api for receiving occassinally and transmiting periodically(in 2 seconds).

The auto-generated usart2 init code

```<code>static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}
</code>```

Interrupt call back code

```<code>void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
    printf("Interrupt error occured(0x%x)!!!\r\n", huart->ErrorCode);
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)
{
    UNUSED(huart);
    if(huart == &huart2 || huart == &huart3){
        uint8_t aEnterLine[] = "\r\n";
        //HAL_UART_Transmit(huart, aEnterLine, sizeof(aEnterLine), 0xFFFF);
        //HAL_UART_Transmit(huart, gRxBuffer, 11, 0xFFFF);
        //HAL_UART_Transmit(huart, aEnterLine, sizeof(aEnterLine), 0xFFFF);
        //printf("%s\r\n", gRxBuffer);
        if(g_cmdExecuting == 0)
            osEventFlagsSet(evt_id, 0x00000001U);
    }else if(huart == &huart1){

    }else{

    }

    HAL_UART_Receive_IT(huart, (unsigned char*)gRxBuffer, 11);
}

int8_t app_usart_transmit(uint8_t* buf, uint8_t len)
{

    return 0;
}

int8_t app_usart_init(UART_HandleTypeDef* huart)
{
    if(huart == NULL)
        return -1;

    if(huart == &huart2 || huart == &huart3){
        uint8_t aTxStartMessage[] = "\r\n****UART-Hyperterminal commmunication based on IT****"
                                    "\r\nEnter 10 characters using keyboard: \r\n";

        HAL_UART_Transmit(huart, aTxStartMessage, sizeof(aTxStartMessage), 0xFFFF);
    }

    clear_rx_buffer();
    HAL_UART_Receive_IT(huart, (uint8_t*)gRxBuffer, 11);
    return 0;
}
</code>```

rx & tx worker code

```<code>extern osMutexId_t myMutex01Handle;
extern osEventFlagsId_t evt_id;
extern osEventFlagsId_t evt_id1;
osTimerId_t timer_id;

static osThreadId gTask1Handle;
static const osThreadAttr_t gTask1Attrbutes = {
    .name = "Task1",
    .priority = (osPriority_t) osPriorityAboveNormal,
    .stack_size = 512
};

static osThreadId gTask2Handle;
static const osThreadAttr_t gTask2Attrbutes = {
    .name = "Task2",
    .priority = (osPriority_t) osPriorityNormal,
    .stack_size = 512
};

uint8_t g_cmdExecuting = 0;
uint8_t g_SemExec = 0;
uint32_t timer_cnt;

void update_stat_timer(void* argument)
{
    timer_cnt++;
    //osMutexAcquire(myMutex01Handle, osWaitForever);
    printf("update_stat_timer executes %u times, ====++++====++++\r\n", timer_cnt);
    //osMutexRelease(myMutex01Handle);
}

void update_stat_task_run(void* argument)
{
    uint32_t count;
    for(;;){
        osDelay(2000);
        count++;
        osMutexAcquire(myMutex01Handle, osWaitForever);
        printf("update_stat_task_run executes %d times, ====++++====++++\r\n", count);
        osMutexRelease(myMutex01Handle);
    }
}

void exec_cmd_task_run(void* argument)
{
    uint32_t flags;

    for(;;){
        flags = osEventFlagsWait(evt_id, 0x00000001U, osFlagsWaitAny, osWaitForever);
        g_cmdExecuting = 1;
        osMutexAcquire(myMutex01Handle, osWaitForever);
        osDelay(1000);
        printf("exec_cmd_task Print\r\n");
        osMutexRelease(myMutex01Handle);
        g_cmdExecuting = 0;
    }
}

int8_t app_task_init()
{
    osStatus_t status;

    gTask1Handle = osThreadNew(exec_cmd_task_run, NULL, &gTask1Attrbutes);
    gTask2Handle = osThreadNew(update_stat_task_run, NULL, &gTask2Attrbutes);

    //uint32_t exec = 1;
    //timer_id = osTimerNew(update_stat_timer, osTimerPeriodic, &exec, NULL);
    //if(status != osOK){
        //;
    //}
    //osTimerStart(timer_id, 2000U);
    return 0;
}
</code>```

My Question:
It could receive and transmit msg at very begining, but after receiving three or four hundred times, it couldn't receive the msg anymore while the transmitting is ok, and I also use the timer api to replace the transmitting thread, the result is the same, it couldn't receive any msg after hundreds times.
the testing result pic

答:
You can perform the HAL status and error checks using uint32_t HAL_UART_GetError(UART_HandleTypeDef * huart) and HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) (http://www.disca.upv.es/aperles/arm_cortex_m3/llibre/st/STM32F439xx_User_Manual/group__uart__exported__functions__group4.html)

The source code for HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) and HAL_UART_RxCplt_Callback() is in https://github.com/ARMmbed/mbed-hal-st-stm32cubef4/blob/master/source/stm32f4xx_hal_uart.c

```<code>HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  uint32_t tmp = 0;

  tmp = huart->State;
  if((tmp == HAL_UART_STATE_READY) || (tmp == HAL_UART_STATE_BUSY_TX))
  {
    if((pData == HAL_NULL ) || (Size == 0))
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(huart);

    huart->pRxBuffPtr = pData;
    huart->RxXferSize = Size;
    huart->RxXferCount = Size;

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    /* Check if a transmit process is ongoing or not */
    if(huart->State == HAL_UART_STATE_BUSY_TX)
    {
      huart->State = HAL_UART_STATE_BUSY_TX_RX;
    }
    else
    {
      huart->State = HAL_UART_STATE_BUSY_RX;
    }

    /* Enable the UART Parity Error Interrupt */
    __HAL_UART_ENABLE_IT(huart, UART_IT_PE);

    /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
    __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);

    /* Process Unlocked */
    __HAL_UNLOCK(huart);

    /* Enable the UART Data Register not empty Interrupt */
    __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
</code>```

Note that the HAL mutually uses locking mechanisms (__HAL_LOCK, code line 107 in https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/TARGET_STM32L1/device/stm32l1xx_hal_def.h)

To get the UART status use i.e.

```<code>HAL_UART_StateTypeDef UARTStatus;
UARTStatus = HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
</code>```

The definition of HAL_UART_StateTypeDef is

```<code>typedef enum
{
  HAL_UART_STATE_RESET             = 0x00,    /*!< Peripheral is not yet Initialized                  */
  HAL_UART_STATE_READY             = 0x01,    /*!< Peripheral Initialized and ready for use           */
  HAL_UART_STATE_BUSY              = 0x02,    /*!< an internal process is ongoing                     */
  HAL_UART_STATE_BUSY_TX           = 0x12,    /*!< Data Transmission process is ongoing               */
  HAL_UART_STATE_BUSY_RX           = 0x22,    /*!< Data Reception process is ongoing                  */
  HAL_UART_STATE_BUSY_TX_RX        = 0x32,    /*!< Data Transmission and Reception process is ongoing */
  HAL_UART_STATE_TIMEOUT           = 0x03,    /*!< Timeout state                                      */
  HAL_UART_STATE_ERROR             = 0x04     /*!< Error                                              */
}HAL_UART_StateTypeDef;
</code>```

(https://github.com/synthetos/Motate/blob/master/MotateProject/motate/cmsis/TARGET_STM/TARGET_DISCO_F407VG/stm32f4xx_hal_uart.h code line 97)

The definition of HAL_StatusTypeDef (general HAL status) is

```<code>typedef enum
{
  HAL_OK       = 0x00,
  HAL_ERROR    = 0x01,
  HAL_BUSY     = 0x02,
  HAL_TIMEOUT  = 0x03
} HAL_StatusTypeDef;
</code>```

You can print the HAL status (i.e. with UART transmit or SWO ITM_SendChar((*ptr++));, see https://ralimtek.com/stm32_debugging/ )

The HAL has its own reference manual, the HAL status is described in the reference manual https://www.st.com/content/ccc/resource/technical/document/user_manual/2f/71/ba/b8/75/54/47/cf/DM00105879.pdf/files/DM00105879.pdf/jcr:content/translations/en.DM00105879.pdf on page 54 in chapter 2.9 HAL common resources.

Debugging techniques are described in https://www.st.com/content/ccc/resource/technical/document/application_note/group0/3d/a5/0e/30/76/51/45/58/DM00354244/files/DM00354244.pdf/jcr:content/translations/en.DM00354244.pdf, also for your programming adapter, that you can directly integrate in CubeMX (i use Atollic with integrated CubeMX because Atollic is based on Eclipse IDE and is almost identical to use)

Another debugging tutorial is https://ardupilot.org/dev/docs/debugging-with-gdb-on-stm32.html (if you are on linux).

This could also be a race condition either of the HAL or the OS. The problem that i have is that you do not post your full code, especially not concerning your OS and this is possibly critical here

So maybe first check the HAL status and then focus on the OS part (race conditions, buffer, stack or heap overflow, ... https://www.st.com/content/ccc/resource/technical/document/user_manual/2d/60/ff/15/8c/c9/43/77/DM00105262.pdf/files/DM00105262.pdf/jcr:content/translations/en.DM00105262.pdf)

Stack overflows are always critical on embedded systems so here is links https://barrgroup.com/embedded-systems/how-to/prevent-detect-stack-overflow , https://www.iar.com/support/resources/articles/detecting-and-avoiding-stack-overflow-in-embedded-systems/

Also see Uart dma receive interrupt stops receiving data after several minutes and  UART receive interrupt stops triggering after several hours of successful receive

Many developers avoid using the HAL because it is a bit buggy and not very transparent, i personally would also not use it when i want full control over the system behavior

Body:
I am developing uart communication on STMicroelectronics NUCLEO-G474RE Board(stm32G474RETX MCU, 64pins) using MDK-v5, but run into a perplexing problem these several days, make no progress on it and have to reach out to seek some help. If anyone could give me a right way to go, it would be appreciated greatly.

Code is not complicated, I use cubeMX to initialize the code base with usart2 configured, and use two threads based on cmsis v2 api for receiving occassinally and transmiting periodically(in 2 seconds).

The auto-generated usart2 init code

static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

Interrupt call back code

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
    printf("Interrupt error occured(0x%x)!!!\r\n", huart->ErrorCode);
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)
{
    UNUSED(huart);
    if(huart == &huart2 || huart == &huart3){
        uint8_t aEnterLine[] = "\r\n";
        //HAL_UART_Transmit(huart, aEnterLine, sizeof(aEnterLine), 0xFFFF);
        //HAL_UART_Transmit(huart, gRxBuffer, 11, 0xFFFF);
        //HAL_UART_Transmit(huart, aEnterLine, sizeof(aEnterLine), 0xFFFF);
        //printf("%s\r\n", gRxBuffer);
        if(g_cmdExecuting == 0)
            osEventFlagsSet(evt_id, 0x00000001U);
    }else if(huart == &huart1){

    }else{

    }

    HAL_UART_Receive_IT(huart, (unsigned char*)gRxBuffer, 11);
}

int8_t app_usart_transmit(uint8_t* buf, uint8_t len)
{

    return 0;
}

int8_t app_usart_init(UART_HandleTypeDef* huart)
{
    if(huart == NULL)
        return -1;

    if(huart == &huart2 || huart == &huart3){
        uint8_t aTxStartMessage[] = "\r\n****UART-Hyperterminal commmunication based on IT****"
                                    "\r\nEnter 10 characters using keyboard: \r\n";

        HAL_UART_Transmit(huart, aTxStartMessage, sizeof(aTxStartMessage), 0xFFFF);
    }

    clear_rx_buffer();
    HAL_UART_Receive_IT(huart, (uint8_t*)gRxBuffer, 11);
    return 0;
}

rx & tx worker code

extern osMutexId_t myMutex01Handle;
extern osEventFlagsId_t evt_id;
extern osEventFlagsId_t evt_id1;
osTimerId_t timer_id;

static osThreadId gTask1Handle;
static const osThreadAttr_t gTask1Attrbutes = {
    .name = "Task1",
    .priority = (osPriority_t) osPriorityAboveNormal,
    .stack_size = 512
};

static osThreadId gTask2Handle;
static const osThreadAttr_t gTask2Attrbutes = {
    .name = "Task2",
    .priority = (osPriority_t) osPriorityNormal,
    .stack_size = 512
};

uint8_t g_cmdExecuting = 0;
uint8_t g_SemExec = 0;
uint32_t timer_cnt;

void update_stat_timer(void* argument)
{
    timer_cnt++;
    //osMutexAcquire(myMutex01Handle, osWaitForever);
    printf("update_stat_timer executes %u times, ====++++====++++\r\n", timer_cnt);
    //osMutexRelease(myMutex01Handle);
}

void update_stat_task_run(void* argument)
{
    uint32_t count;
    for(;;){
        osDelay(2000);
        count++;
        osMutexAcquire(myMutex01Handle, osWaitForever);
        printf("update_stat_task_run executes %d times, ====++++====++++\r\n", count);
        osMutexRelease(myMutex01Handle);
    }
}

void exec_cmd_task_run(void* argument)
{
    uint32_t flags;

    for(;;){
        flags = osEventFlagsWait(evt_id, 0x00000001U, osFlagsWaitAny, osWaitForever);
        g_cmdExecuting = 1;
        osMutexAcquire(myMutex01Handle, osWaitForever);
        osDelay(1000);
        printf("exec_cmd_task Print\r\n");
        osMutexRelease(myMutex01Handle);
        g_cmdExecuting = 0;
    }
}

int8_t app_task_init()
{
    osStatus_t status;

    gTask1Handle = osThreadNew(exec_cmd_task_run, NULL, &gTask1Attrbutes);
    gTask2Handle = osThreadNew(update_stat_task_run, NULL, &gTask2Attrbutes);

    //uint32_t exec = 1;
    //timer_id = osTimerNew(update_stat_timer, osTimerPeriodic, &exec, NULL);
    //if(status != osOK){
        //;
    //}
    //osTimerStart(timer_id, 2000U);
    return 0;
}

My Question:
It could receive and transmit msg at very begining, but after receiving three or four hundred times, it couldn't receive the msg anymore while the transmitting is ok, and I also use the timer api to replace the transmitting thread, the result is the same, it couldn't receive any msg after hundreds times.
the testing result pic

Body:
You can perform the HAL status and error checks using uint32_t HAL_UART_GetError(UART_HandleTypeDef * huart) and HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) (http://www.disca.upv.es/aperles/arm_cortex_m3/llibre/st/STM32F439xx_User_Manual/group__uart__exported__functions__group4.html)

The source code for HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) and HAL_UART_RxCplt_Callback() is in https://github.com/ARMmbed/mbed-hal-st-stm32cubef4/blob/master/source/stm32f4xx_hal_uart.c

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  uint32_t tmp = 0;

  tmp = huart->State;
  if((tmp == HAL_UART_STATE_READY) || (tmp == HAL_UART_STATE_BUSY_TX))
  {
    if((pData == HAL_NULL ) || (Size == 0))
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(huart);

    huart->pRxBuffPtr = pData;
    huart->RxXferSize = Size;
    huart->RxXferCount = Size;

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    /* Check if a transmit process is ongoing or not */
    if(huart->State == HAL_UART_STATE_BUSY_TX)
    {
      huart->State = HAL_UART_STATE_BUSY_TX_RX;
    }
    else
    {
      huart->State = HAL_UART_STATE_BUSY_RX;
    }

    /* Enable the UART Parity Error Interrupt */
    __HAL_UART_ENABLE_IT(huart, UART_IT_PE);

    /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
    __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);

    /* Process Unlocked */
    __HAL_UNLOCK(huart);

    /* Enable the UART Data Register not empty Interrupt */
    __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

Note that the HAL mutually uses locking mechanisms (__HAL_LOCK, code line 107 in https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/TARGET_STM32L1/device/stm32l1xx_hal_def.h)

To get the UART status use i.e.

HAL_UART_StateTypeDef UARTStatus;
UARTStatus = HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

The definition of HAL_UART_StateTypeDef is

typedef enum
{
  HAL_UART_STATE_RESET             = 0x00,    /*!< Peripheral is not yet Initialized                  */
  HAL_UART_STATE_READY             = 0x01,    /*!< Peripheral Initialized and ready for use           */
  HAL_UART_STATE_BUSY              = 0x02,    /*!< an internal process is ongoing                     */
  HAL_UART_STATE_BUSY_TX           = 0x12,    /*!< Data Transmission process is ongoing               */
  HAL_UART_STATE_BUSY_RX           = 0x22,    /*!< Data Reception process is ongoing                  */
  HAL_UART_STATE_BUSY_TX_RX        = 0x32,    /*!< Data Transmission and Reception process is ongoing */
  HAL_UART_STATE_TIMEOUT           = 0x03,    /*!< Timeout state                                      */
  HAL_UART_STATE_ERROR             = 0x04     /*!< Error                                              */
}HAL_UART_StateTypeDef;

(https://github.com/synthetos/Motate/blob/master/MotateProject/motate/cmsis/TARGET_STM/TARGET_DISCO_F407VG/stm32f4xx_hal_uart.h code line 97)

The definition of HAL_StatusTypeDef (general HAL status) is

typedef enum
{
  HAL_OK       = 0x00,
  HAL_ERROR    = 0x01,
  HAL_BUSY     = 0x02,
  HAL_TIMEOUT  = 0x03
} HAL_StatusTypeDef;

You can print the HAL status (i.e. with UART transmit or SWO ITM_SendChar((*ptr++));, see https://ralimtek.com/stm32_debugging/ )

The HAL has its own reference manual, the HAL status is described in the reference manual https://www.st.com/content/ccc/resource/technical/document/user_manual/2f/71/ba/b8/75/54/47/cf/DM00105879.pdf/files/DM00105879.pdf/jcr:content/translations/en.DM00105879.pdf on page 54 in chapter 2.9 HAL common resources.

Debugging techniques are described in https://www.st.com/content/ccc/resource/technical/document/application_note/group0/3d/a5/0e/30/76/51/45/58/DM00354244/files/DM00354244.pdf/jcr:content/translations/en.DM00354244.pdf, also for your programming adapter, that you can directly integrate in CubeMX (i use Atollic with integrated CubeMX because Atollic is based on Eclipse IDE and is almost identical to use)

Another debugging tutorial is https://ardupilot.org/dev/docs/debugging-with-gdb-on-stm32.html (if you are on linux).

This could also be a race condition either of the HAL or the OS. The problem that i have is that you do not post your full code, especially not concerning your OS and this is possibly critical here

So maybe first check the HAL status and then focus on the OS part (race conditions, buffer, stack or heap overflow, ... https://www.st.com/content/ccc/resource/technical/document/user_manual/2d/60/ff/15/8c/c9/43/77/DM00105262.pdf/files/DM00105262.pdf/jcr:content/translations/en.DM00105262.pdf)

Stack overflows are always critical on embedded systems so here is links https://barrgroup.com/embedded-systems/how-to/prevent-detect-stack-overflow , https://www.iar.com/support/resources/articles/detecting-and-avoiding-stack-overflow-in-embedded-systems/

Also see Uart dma receive interrupt stops receiving data after several minutes and  UART receive interrupt stops triggering after several hours of successful receive

Many developers avoid using the HAL because it is a bit buggy and not very transparent, i personally would also not use it when i want full control over the system behavior


问:
ef core navigation property fails to load
My application is Ef core 2.2 , Lazy loading not enabled.

At MapAddress method address object's Country object is null, although i have

Include(a => a.Address).ThenInclude(a => a.Country)

to load country eagerly.

```<code>   var agentWalletResponse = (from wd in dbContext.WalletDetail.Where(w => w.WalletDetailId == agentWalletDetailId)
                                    join c in dbContext.CorporateInfo.Include(a => a.Address).ThenInclude(a => a.Country).Where(d => !d.IsDeleted) on wd.WalletSubscriptionId equals c.OwnerUserId
                                    select new AgentWalletResponse()
                                    {

                                        Address = MapAddress(c.Address),
                                        Balance = wd.AvailableBalance,
                                        CreatedOn = wd.CreatedOn
                                    }).FirstOrDefault();
</code>```

Map address

```<code> protected AddressModel MapAddress(Address address)
    {
        if (address == null)
            return null;

        return new AddressModel
        {
            AddressId = address.AddressId,
            AddressLine = address.AddressLine1,
            City = address.City,
            Country = address.Country?.Name,
            Province = address.Province,
            Division = address.Division,
            PhoneNumber = address.PhoneNumber,
            PostalCode = address.PostalCode
        };
    }
</code>```

答:
use this

var agentWalletResponse = (from wd in dbContext.WalletDetail.Where(w => w.WalletDetailId == agentWalletDetailId)
                                    join c in dbContext.CorporateInfo.Include(a => a.Address).ThenInclude(a => a.Country).Where(d => !d.IsDeleted) on wd.WalletSubscriptionId equals c.OwnerUserId
                                    select new AgentWalletResponse()
                                    {
                                        Address = new AddressModel
                                        {
                                          AddressId = c.Address.AddressId,
                                          AddressLine = c.Address.AddressLine1,
                                          City = c.Address.City,
                                          Country = c.Address.Country?.Name,
                                          Province = c.Address.Province,
                                          Division = c.Address.Division,
                                          PhoneNumber = c.Address.PhoneNumber,
                                          PostalCode = c.Address.PostalCode
                                        },
                                        Balance = wd.AvailableBalance,
                                        CreatedOn = wd.CreatedOn
                                    }).FirstOrDefault();
```

Body:
My application is Ef core 2.2 , Lazy loading not enabled.

At MapAddress method address object's Country object is null, although i have

Include(a => a.Address).ThenInclude(a => a.Country)

to load country eagerly.

   var agentWalletResponse = (from wd in dbContext.WalletDetail.Where(w => w.WalletDetailId == agentWalletDetailId)
                                    join c in dbContext.CorporateInfo.Include(a => a.Address).ThenInclude(a => a.Country).Where(d => !d.IsDeleted) on wd.WalletSubscriptionId equals c.OwnerUserId
                                    select new AgentWalletResponse()
                                    {

                                        Address = MapAddress(c.Address),
                                        Balance = wd.AvailableBalance,
                                        CreatedOn = wd.CreatedOn
                                    }).FirstOrDefault();

Map address

 protected AddressModel MapAddress(Address address)
    {
        if (address == null)
            return null;

        return new AddressModel
        {
            AddressId = address.AddressId,
            AddressLine = address.AddressLine1,
            City = address.City,
            Country = address.Country?.Name,
            Province = address.Province,
            Division = address.Division,
            PhoneNumber = address.PhoneNumber,
            PostalCode = address.PostalCode
        };
    }


问:
Binding CornerRadius to two boolean properties
Let's say I have a Border whose DataContext is an object of type MyViewModel. MyViewModel has bool properties called RoundLeft and RoundRight. When RoundLeft is true, I want the CornerRadius of the border to be 6,0,0,6. When RoundRight is true, I want 0,6,6,0. When both are true, I want 6,6,6,6.

I've described my first two attempts below. I haven't given up yet, but I wanted to see if anyone else might have any ideas.

Attempt #1

I got it partially working by binding to the MyViewModel instance itself (not a specific property) and using an IValueConverter that builds the correct CornerRadius object. This works on initial load. The problem is that the binding is monitoring changes of the object as a whole rather than changes to the specific RoundLeft and RoundRight properties, e.g. if RoundLeft changes, the border's CornerRadius doesn't.

Binding:

```<code><Border CornerRadius="{Binding Converter={StaticResource myShiftCornerRadiusConverter}}" />
</code>```

Converter:

```<code>public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var myViewModel = value as MyViewModel;
        if (myViewModel != null)
        {
            return new CornerRadius(
                myViewModel.RoundLeft ? 6 : 0,
                myViewModel.RoundRight ? 6 : 0,
                myViewModel.RoundRight ? 6 : 0,
                myViewModel.RoundLeft ? 6 : 0);
        }
        else
        {
            return new CornerRadius(6);
        }
    }
</code>```

Attempt #2

This blog post from Colin Eberhardt looked promising, but I'm getting vague XamlParseExceptions and ComExceptions. Here's my XAML:

```<code><Border>
<ce:MultiBindings>
    <ce:MultiBinding TargetProperty="CornerRadius" Converter="{StaticResource myCornerRadiusConverter}">
        <ce:MultiBinding.Bindings>
            <ce:BindingCollection>
                <Binding Path="RoundLeft" />
                <Binding Path="RoundRight" />
            </ce:BindingCollection>
        </ce:MultiBinding.Bindings>
    </ce:MultiBinding>
</ce:MultiBindings>
</Border>
</code>```

Here's my converter, although the execution never gets this far, i.e. my breakpoint is never hit.

```<code>public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values.Length == 2 && values.All(v => v is bool))
        {
            var roundLeft = (bool)values[0];
            var roundRight = (bool)values[1];

            return new CornerRadius(
                roundLeft ? 6 : 0,
                roundRight ? 6 : 0,
                roundRight ? 6 : 0,
                roundLeft ? 6 : 0);
        }
        else
        {
            return new CornerRadius(6);
        }
    }
</code>```

答:
Lack of built in MultiBinding support in SL makes this a bit of a pain but how about a simpler (albeit slightly more coupled) approach.

Since you already have  roundLeft and roundRight properties in your VM that is already somewhat coupled to a specific UI paradigm. So why not just have a computed property that returns a CornerRadius value and just bind to that?

So for instance, when you change roundLeft you call a method to update the computed CornerRadius property and raise a change notification on that property and then your view binds to the computed CornerRadius property.

ContentLicense: CC BY-SA 3.0

Body:
Let's say I have a Border whose DataContext is an object of type MyViewModel. MyViewModel has bool properties called RoundLeft and RoundRight. When RoundLeft is true, I want the CornerRadius of the border to be 6,0,0,6. When RoundRight is true, I want 0,6,6,0. When both are true, I want 6,6,6,6.

I've described my first two attempts below. I haven't given up yet, but I wanted to see if anyone else might have any ideas.

Attempt #1

I got it partially working by binding to the MyViewModel instance itself (not a specific property) and using an IValueConverter that builds the correct CornerRadius object. This works on initial load. The problem is that the binding is monitoring changes of the object as a whole rather than changes to the specific RoundLeft and RoundRight properties, e.g. if RoundLeft changes, the border's CornerRadius doesn't.

Binding:

<Border CornerRadius="{Binding Converter={StaticResource myShiftCornerRadiusConverter}}" />

Converter:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var myViewModel = value as MyViewModel;
        if (myViewModel != null)
        {
            return new CornerRadius(
                myViewModel.RoundLeft ? 6 : 0,
                myViewModel.RoundRight ? 6 : 0,
                myViewModel.RoundRight ? 6 : 0,
                myViewModel.RoundLeft ? 6 : 0);
        }
        else
        {
            return new CornerRadius(6);
        }
    }

Attempt #2

This blog post from Colin Eberhardt looked promising, but I'm getting vague XamlParseExceptions and ComExceptions. Here's my XAML:

<Border>
<ce:MultiBindings>
    <ce:MultiBinding TargetProperty="CornerRadius" Converter="{StaticResource myCornerRadiusConverter}">
        <ce:MultiBinding.Bindings>
            <ce:BindingCollection>
                <Binding Path="RoundLeft" />
                <Binding Path="RoundRight" />
            </ce:BindingCollection>
        </ce:MultiBinding.Bindings>
    </ce:MultiBinding>
</ce:MultiBindings>
</Border>

Here's my converter, although the execution never gets this far, i.e. my breakpoint is never hit.

public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values.Length == 2 && values.All(v => v is bool))
        {
            var roundLeft = (bool)values[0];
            var roundRight = (bool)values[1];

            return new CornerRadius(
                roundLeft ? 6 : 0,
                roundRight ? 6 : 0,
                roundRight ? 6 : 0,
                roundLeft ? 6 : 0);
        }
        else
        {
            return new CornerRadius(6);
        }
    }