TransWikia.com

WPF c# Binding, привязки

Stack Overflow на русском Asked on December 11, 2021

Есть UserControl в виде кастомного текстбокса. У него свойсво SetText отвечает за текст в текстбоксе.
TextBoxCustom расположен в LoginUC(UserControl в виде панели входа). В LoginViewModel(вьюмодель LoginUC) есть свойство LoginText. Когда ввожу что-то в кастомный текстбокс, то привязанное свойство LoginText не меняется. Может, что-то с привязками или DependencyProperty не то сделал.

TextBoxCustom.xaml.cs

public partial class TextBoxCustom2  : UserControl
    {
        public TextBoxCustom2()
        {
            InitializeComponent();
        }

        public Brush BorderColor
        {
            get { return dd.BorderBrush; }
            set { dd.BorderBrush = value;}
        }
        
        public static readonly DependencyProperty SetTextProperty =
            DependencyProperty.Register("SetText", typeof(string), typeof(TextBoxCustom2));

        public string SetText
        {
            get { return (string)GetValue(SetTextProperty);}
            set { SetValue(SetTextProperty, value); txtbox.Text = value; }
        }
        }

TextBoxCustom.xaml

  <UserControl x:Class="Progect1.TextBoxCustom2"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:Progect1"
                 mc:Ignorable="d" 
                 d:DesignHeight="20" d:DesignWidth="100">
        <UserControl.Resources>
            <SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
            <SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
            <SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>
            <Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}">
                <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
                <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                <Setter Property="BorderThickness" Value="1"/>
                <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
                <Setter Property="HorizontalContentAlignment" Value="Left"/>
                <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                <Setter Property="AllowDrop" Value="true"/>
                <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
                <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TextBox}">
                            <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                                <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>   
            </Style>
        </UserControl.Resources>
        <Grid RenderOptions.BitmapScalingMode="NearestNeighbor">
            <Border RenderOptions.BitmapScalingMode="NearestNeighbor" SnapsToDevicePixels="True" Name="dd" CornerRadius="12" Padding="2" BorderThickness="1" Background="#FF303339" BorderBrush="Black" >
                <TextBox Text="{Binding SetText,UpdateSourceTrigger=PropertyChanged}" Name="txtbox" Margin="7,-1.125" BorderBrush="{x:Null}" Background="{x:Null}" SelectionBrush="#FF0094FB" CaretBrush="#FFCCCDCE" Foreground="#FFCCCDCE" Style="{DynamicResource TextBoxStyle1}" FontFamily="Segoe UI Symbol" FontSize="16" TextAlignment="Center" FontWeight="Bold" />            
 </Border>
        </Grid>
    </UserControl>

LoginUC.xaml

 <UserControl x:Class="Progect1.Views.Auth.LoginUC"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:Progect1.Views.Auth" 
                 xmlns:lt="clr-namespace:Progect1" 
                 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
                 mc:Ignorable="d">
        <Grid>
            <Border CornerRadius="12" Padding="2" BorderThickness="1" Background="#FF202225" Margin="117,0,117.522,62.283" Height="292" VerticalAlignment="Bottom" Grid.ColumnSpan="2">
                <Grid >
                    <TextBlock HorizontalAlignment="Left" Height="23.333" TextWrapping="Wrap" Text="Логин" VerticalAlignment="Top" Width="266" FontFamily="Segoe UI Symbol" FontWeight="Bold" TextAlignment="Center" FontSize="20" Foreground="#FFB9B9B9" Margin="0,17.003,0,0"/>
                    <TextBlock HorizontalAlignment="Left" Height="27.333" Margin="0,87.819,0,0" TextWrapping="Wrap" Text="Пароль" VerticalAlignment="Top" Width="266" FontFamily="Segoe UI Symbol" FontWeight="Bold" TextAlignment="Center" FontSize="20" Foreground="#FFB9B9B9"/>
                    <lt:LoginButton Height="48" Margin="53,195.664,52,0" Width="Auto" VerticalAlignment="Top">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Click">
                                <i:InvokeCommandAction Command="{Binding Log}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </lt:LoginButton>
                    <lt:TextBoxCustom2 SetText="{Binding LoginText, UpdateSourceTrigger=PropertyChanged}" x:Name="logintxtbox" Height="26.5" Margin="18.148,45,17,0" VerticalAlignment="Top">
                    </lt:TextBoxCustom2>
                    <lt:TextBoxCustom2  Height="26.5" Margin="18.148,118.343,17,0" VerticalAlignment="Top"/>
                </Grid>
            </Border>
        </Grid>
    </UserControl>

LoginViewModel.cs

public class LoginViewModel : BaseViewModel
    {
        private AuthViewModel VM;
        public LoginViewModel(AuthViewModel vm)
        {
            VM = vm;
        }

        private RelayCommand logcommand;
        public RelayCommand Log
        {
            get
            {
                return logcommand ??
                    (logcommand = new RelayCommand(obj =>
                    {
                        System.Windows.MessageBox.Show($"{LoginText}");
                    }));
            }
        }

        private string _logintext;
        public  string LoginText
        {
            get { return _logintext; }
            set
            {
                _logintext = value;     
                OnPropertyChanged("LoginText");
            }
        }
    }

One Answer

Для начала, у вас UserControl не знает от куда брать свойства. Самый простой способ указания источника, это имя контрола.

  • Указываем у контрола в TextBoxCustom.xaml имя: <UserControl x:Name="uc" ... >

  • Используем это имя в нужных привязках:

    <TextBox Text="{Binding SetText, ElementName=uc}"
    

Другой вариант, это через RelativeSource:

<TextBox Text="{Binding SetText, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"

Следующая проблема у вас заключается в том, что привязка к DependencyProperty идет в режиме OneWay, то есть из свойства взять можем, а в свойство положить не можем. Решение тут довольно простое и их два:

  1. Можно задать в привязке какой режим нам нужен:

    <lt:TextBoxCustom2 SetText="{Binding LoginText, Mode=TwoWay}" ... >
    
  2. Мы можем задать его в самом DependencyProperty, прописав там примерно такое:

    public static readonly DependencyProperty SetTextProperty =
        DependencyProperty.Register("SetText", typeof(string), 
            typeof(TextBoxCustom2), 
            new FrameworkPropertyMetadata(default, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    

Собственно эти две вещи должны решить вашу проблему.

Answered by EvgeniyZ on December 11, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP