WPF - Commands i INotifyPropertyChanged

0

Witam,

Mam problem z implementacją ICommands i INotifyPropertyChanged. Co chcę osiągnąc? Docelowo sprawdzić czy 4 textboxy mają wartość i wtedy ustawić button na enabled. W ramach testu natomiast (i na tym się skupmy) mam buttona i check boxa. Button ma być włączony tylko w momencie kiedy check box jest zaznaczony i odwrotnie kiedy check box jest odznaczony button ma być wyłączony. Korzystałem z:
https://wellsb.com/csharp/learn/wpf-data-binding-csharp-inotifypropertychanged/
http://blog.kokosa.net/post/MemoryVisualizer-WPF-oraz-ICommand

Oddzielnie wszystko działa natomiast nie potrafię tego połączyć w całość. Czy ma ktoś dobry tutorial związany z tym co chcę osiągnąć? Jeśli nie to wrzucam kod ;)

Pozdrawiam

0

Cześć, jeżeli chcesz sterować włączeniem/wyłączeniem przycisku przy pomocy ChckBox-a, to najłatwiej zbindować właściwość **IsChecked **tego CheckBox-a z właściwością **IsEnabled **przycisku:

<Window x:Class="ButtonCheckBoxExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ButtonCheckBoxExample"
        mc:Ignorable="d"
        Title="MainWindow" Height="100" Width="250">
    <StackPanel>
        <CheckBox x:Name="myCheckBox" Content="włącz/wyłącz przycisk" IsChecked="True"/>
        <Button x:Name="myButton" Content="Ala ma kota" IsEnabled="{Binding ElementName=myCheckBox, Path=IsChecked}"/>
    </StackPanel>
</Window>

0

Hej,

Dzięki za odpowiedź. To jak najbardziej super działa w przypadku jednego CheckBoxa. Co w przypadku kiedy mam więcej CheckBoxów? Jak to wtedy zbindować? Docelowo byłyby to TextBoxy sprawdzane pod kątem zawartości.

Pozdrawiam

1

Hej,
jeżeli Button ma być włączony gdy wszystkie cztery TexBox-y mają jakąś zawartość, to można w tym Button-ie dodać trigger-y reagujące na długość tekstu wpisanego w każde pole.

Przykład poniżej działa tak, że Button jest włączony tylko wtedy, gdy wszystkie pola zawierają jakiś tekst, jeżeli którekolwiek pole jest puste Button jest wyłączony (Button.IsEnabled = false gdy Text.Length == 0)

<Window x:Class="ButtonCheckBoxExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ButtonCheckBoxExample"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="580">

    <Window.Resources>
        <local:MyEnableConverter x:Key="myEnableConverter"/>
    </Window.Resources>
    
    <StackPanel>
        <TextBox x:Name="textBox01" Text="tekst 1" Margin="10"/>
        <TextBox x:Name="textBox02" Text="tekst 2" Margin="10"/>
        <TextBox x:Name="textBox03" Text="tekst 3" Margin="10"/>
        <TextBox x:Name="textBox04" Text="tekst 4" Margin="10"/>

        <Button x:Name="myButton" Content="OK" Margin="10">
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Style.Triggers>

                        <DataTrigger  Binding="{Binding ElementName=textBox01, Path=Text.Length}" Value="0">
                            <Setter Property="IsEnabled" Value="False"/>
                        </DataTrigger>

                        <DataTrigger  Binding="{Binding ElementName=textBox02, Path=Text.Length}" Value="0">
                            <Setter Property="IsEnabled" Value="False"/>
                        </DataTrigger>

                        <DataTrigger  Binding="{Binding ElementName=textBox03, Path=Text.Length}" Value="0">
                            <Setter Property="IsEnabled" Value="False"/>
                        </DataTrigger>

                        <DataTrigger  Binding="{Binding ElementName=textBox04, Path=Text.Length}" Value="0">
                            <Setter Property="IsEnabled" Value="False"/>
                        </DataTrigger>

                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>

    </StackPanel>
</Window>

0

Dziękuje panowie za pomoc. Poniżej w pełni działający kod:

xaml:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <local:MultiValueConverter x:Key="MultiValueConverter" />
    </Window.Resources>
    <Grid>
        <Canvas x:Name="myCanvas" HorizontalAlignment="Left" Height="225" Margin="70,70,0,0" VerticalAlignment="Top" Width="595">
            <TextBox x:Name="tb1" Text="{Binding TextOne, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="24" Canvas.Left="35" TextWrapping="Wrap" Canvas.Top="36" Width="120"/>
            <TextBox x:Name="tb2" Text="{Binding TextTwo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="23" Canvas.Left="200" TextWrapping="Wrap" Canvas.Top="37" Width="120"/>
            <TextBox x:Name="tb3" Text="{Binding TextThree, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="23" Canvas.Left="375" TextWrapping="Wrap" Canvas.Top="36" Width="120"/>
            <Button x:Name="btn1" Content="Button1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Canvas.Left="80" Canvas.Top="155">
                <Button.IsEnabled>
                    <MultiBinding Converter="{StaticResource MultiValueConverter}">
                        <Binding Path="TextOne" />
                        <Binding Path="TextTwo" />
                        <Binding Path="TextThree" />
                    </MultiBinding>
                </Button.IsEnabled>
            </Button>
            <Label x:Name="lbl1" Content="Label" Canvas.Left="80" Canvas.Top="105"/>
        </Canvas>
    </Grid>
</Window>

MultiValueConverter:

    public class MultiValueConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            string one = values[0] as string;
            string two = values[1] as string;
            string three = values[2] as string;

            if (!string.IsNullOrEmpty(one) && !string.IsNullOrEmpty(two) && !string.IsNullOrEmpty(three))
                return true;

            return false;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

DataContext class:

namespace WpfApp1
{
    public class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {

        }

        public event PropertyChangedEventHandler PropertyChanged;

        private string _textOne;

        public string TextOne
        {
            get { return _textOne; }
            set
            {
                _textOne = value;
                NotifyPropertyOnChange(nameof(TextOne));
            }
        }

        private string _textTwo;

        public string TextTwo
        {
            get { return _textTwo; }
            set
            {
                _textTwo = value;
                NotifyPropertyOnChange(nameof(TextTwo));
            }
        }

        private string _textThree;

        public string TextThree
        {
            get { return _textThree; }
            set
            {
                _textThree = value;
                NotifyPropertyOnChange(nameof(TextThree));
            }
        }

        public void NotifyPropertyOnChange(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Bindowanie DataContextu:

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainViewModel();
        }

1 użytkowników online, w tym zalogowanych: 0, gości: 1