Pytanie XAML Wiązanie z przeciwieństwem innego elementu


Rozwijam proste ćwiczenie i chcę się dowiedzieć, czy istnieje sposób na połączenie z przeciwieństwem innego elementu przy użyciu tylko XAML. Na przykład. Mam dwa przyciski na formularzu, Start i Stop na zegar. Nie chcę, aby oba były włączone w tym samym czasie. Po uruchomieniu programu przycisk zatrzymania powinien być wyłączony. Po kliknięciu przycisku Start należy go wyłączyć, a przycisk Stop włączyć. Następnie na odwrót, aż użytkownik zakończy pracę.

Wiem, że są na to lepsze kontrole i wiem, że jest to łatwe do zrobienia w kodzie. Chciałem tylko wiedzieć, czy istnieje jakiś operator NOT w XAML, który mógłby wyglądać tak:

<Button Content="_Start" Name="btnStart"/>
<Button Content="_Stop" Name="btnStop"
        IsEnabled="{Binding ElementName=btnStart,
                    Path=Not(IsEnabled)}"/>

Lub coś takiego:

                    Path != IsEnabled}"/>

Lub nawet coś takiego:

                    Path=IsEnabled.Not()}"/>

Wiem, że mogę powiązać bezpośrednio z przyciskiem start, ale gdy jest włączony, to jest drugi, i podobnie, gdy jest wyłączony. Zobacz, skąd przychodzę.

Byłbym nawet skłonny do przyjęcia pewnego rodzaju walidacji XAML, która najpierw sprawdzi stan przycisku startowego i wymusi stan zatrzymania, który będzie przeciwny. Lub inne podobne hacki lub obejścia, które nie wymagają codebehind.

Dzięki za każdą okazaną pomoc.

EDYCJE: Pamiętaj, że kluczowym punktem tego jest brak kodu NO. Jeśli muszę napisać jedną linię kodu, równie dobrze mogę użyć obsługi zdarzeń onclick i prostego operatora:. Więc chcę tylko coś, co będzie działać bezpośrednio w XAML.


10
2017-09-24 15:02


pochodzenie




Odpowiedzi:


Nie ma Not operacja po wyjęciu z pudełka. Jednak łatwo to osiągnąć za pomocą niestandardowego konwertera:

public class NotConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return !(bool) value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return !(bool)value;
    }
}

Następnie możesz określić go jako konwerter na oprawie.

<Button Content="_Stop" Name="btnStop"
    IsEnabled="{Binding ElementName=btnStart, Converter={StaticResource NotConverter} Path=IsEnabled}"/>

I wreszcie utwórz zasób na swoim oknie / stronie o nazwie NotConverter:

<Window.Resources>
    <ns:NotConverter x:Key="NotConverter" />
</Window.Resources>

Możesz uzyskać więcej informacji na temat IValueConverter od MSDN.

Następnie możesz użyć tego konwertera wartości w dowolnym miejscu. Możesz wyciągnąć go z zasobów Window i uczynić go zasobem na poziomie aplikacji, więc nie musisz go określać w każdym oknie.


16
2017-09-24 15:12



@FrancisRodgers Jeśli chcesz sobie poradzić z wydarzeniem kliknięcia, to w porządku. Ale musisz tylko zapisać ten konwerter wartości pewnego razu. Kiedy dzieje się, gdy potrzebujesz 17 przycisków? Napisz procedurę obsługi kliknięć dla wszystkich 17 lub napisz konwerter wartości jeden raz? Jest wielokrotnego użytku. - vcsjones
Ok, widzę twój punkt widzenia. Bardzo dobrze zrobione. Dziękuję Ci. Nadal chciałbym wiedzieć, czy mogę to zrobić za pomocą reguł sprawdzania poprawności i bez kodu. Dla żartu. - Francis Rodgers
Korzystając z tej metody, pojawia się błąd: "Nie znaleziono typu ns: NotConverter. Sprawdź, czy nie brakuje referencji zespołu i czy zostały utworzone wszystkie zestawy referencji". Jak mam to naprawić? Dzięki jeszcze raz. - Francis Rodgers
@FrancisRodgers - Upewnij się, że dodasz xmlns do swojego okna / aplikacji ns która jest przestrzenią nazw miejsca, w którym wpisujesz typ. Na przykład xmlns:ns="clr-namespace:Your.Namespace.Here" - vcsjones
@FrancisRodgers Możesz dowiedzieć się więcej o XAML i przestrzeni nazw na msdn.microsoft.com/en-us/library/ms747086.aspx - vcsjones


Jeśli wiem, że to prawda, nie możesz powiązać się z! Property, ale możesz napisać IValueConverter i użyć go do wiązania. Poniżej wyjaśniono szczegółowo, w jaki sposób można skonfigurować IValueConverter, który zwraca wartość Boated Negated.

IValueConverter, aby zanegować właściwość


3
2017-09-24 15:10



jeśli zrobisz to bez kodu, tylko w XAML, możesz wyjaśnić jak. Wiem, że mogę użyć do tego kodu, ale jeśli muszę napisać pojedynczą linię kodu, równie dobrze mogę wykonać całą operację w kodzie, ponieważ będzie to łatwe do opanowania i zrozumienia. Tak naprawdę to, czego szukam, to niektóre zaawansowane XAML, których nie widziałbyś na co dzień. Nawet lepiej, jeśli jest to proste XAML, o ile jest to XAML bez żadnego kodu. - Francis Rodgers
Pod linkiem, który mam w mojej odpowiedzi, możesz przeczytać odpowiedź Jobi Joy, mówi, że z XAML Mark up Extension możliwe jest zrobienie tego w xaml, ale jest to sposób na dużo pracy. I myślę, że opcja IValueConverter jest najlepsza, ponieważ możesz ponownie użyć konwertera w przyszłości, a to jest bardzo proste w rzeczywistości 2 linie kodu w konwersji i konwersji z powrotem metod, a następnie musisz dodać zasób do aplikacji, nie " t zapomnij dodać Przestrzeń nazw Konwertery do swojego XAML, a następnie będziesz mógł używać konwertera w swoich powiązaniach z konwerterem = {StatickResource convertersresourcename} - BigL