我的 WPF 應用程式中有一個用戶控制元件,它基本上是一個復選框和文本框。我希望根據復選框狀態禁用或啟用文本框,并且狀態是資料可系結的。
這是我的用戶控制元件:
XAML
<UserControl x:Class="WpfApp.Views.Elements.TextCheckBox"
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"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<CheckBox Content="Disabled"
IsChecked="{Binding CheckBoxChecked,
Mode=OneWayToSource,
UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1"
Grid.Column="1"
Margin="5,5,8,5"/>
<TextBox Text="{Binding TextBoxText,
Mode=OneWayToSource,
UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
IsEnabled="{Binding TextBoxEnabled,
Mode=OneWay,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
Grid.Row="1"
Grid.Column="0"
Height="20"/>
</Grid>
</UserControl>
代碼隱藏
using System.Windows;
using System.Windows.Controls;
namespace WpfApp.Views.Elements
{
/// <summary>
/// Interaction logic for TextCheckBox.xaml
/// </summary>
public partial class TextCheckBox : UserControl
{
public bool TextBoxEnabled => !CheckBoxChecked;
public string TextBoxText
{
get => (string)GetValue(TextBoxTextProperty);
set => SetValue(TextBoxTextProperty, value);
}
public bool CheckBoxChecked
{
get => (bool)GetValue(CheckBoxCheckedProperty);
set => SetValue(CheckBoxCheckedProperty, value);
}
public event DependencyPropertyChangedEventHandler TextPropertyChanged;
public static readonly DependencyProperty TextBoxTextProperty =
DependencyProperty.Register(nameof(TextBoxText), typeof(string), typeof(TextCheckBox), new PropertyMetadata(OnAnyPropertyChanged));
public static readonly DependencyProperty CheckBoxCheckedProperty =
DependencyProperty.Register(nameof(CheckBoxChecked), typeof(bool), typeof(CheckBoxInput), new PropertyMetadata(OnAnyPropertyChanged));
public TextCheckBox()
=> InitializeComponent();
static void OnAnyPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
=> (obj as TextCheckBox).OnAnyPropertyChanged(args);
void OnAnyPropertyChanged(DependencyPropertyChangedEventArgs args)
=> TextPropertyChanged?.Invoke(this, args);
}
}
我不知道如何在選中復選框時告訴 TextCheckBox 更新其“IsEnabled”屬性。
這是我使用 TextCheckBox 并且系結作業正常的 XAML:
<UserControl x:Class="WpfApp.Views.MyView"
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:other="clr-namespace:WpfApp.Other" xmlns:elements="clr-namespace:WpfApp.Views.Elements"
mc:Ignorable="d"
other:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<elements:TextCheckBox
CheckBoxChecked="{Binding IsChecked,
Mode=OneWayToSource}"
TextBoxText="{Binding TextContent,
Mode=OneWayToSource,
UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</UserControl>
編輯:
正如Khiro 所建議的,我嘗試使用一個依賴屬性,它的值是在“CheckBoxChecked”的設定器中設定的。
這是更改后的代碼隱藏(更改后的代碼在上一行用注釋“在此處更改”注釋):
using System.Windows;
using System.Windows.Controls;
namespace WpfApp.Views.Elements
{
/// <summary>
/// Interaction logic for TextCheckBox.xaml
/// </summary>
public partial class TextCheckBox : UserControl
{
// Change here.
public bool TextBoxEnabled => (bool)GetValue(TextBoxEnabledProperty);
public string TextBoxText
{
get => (string)GetValue(TextBoxTextProperty);
set => SetValue(TextBoxTextProperty, value);
}
public bool CheckBoxChecked
{
get => (bool)GetValue(CheckBoxCheckedProperty);
set
{
SetValue(CheckBoxCheckedProperty, value);
// Change here.
SetValue(TextBoxEnabledProperty, !value);
}
}
public event DependencyPropertyChangedEventHandler TextPropertyChanged;
// Change here.
public static readonly DependencyProperty TextBoxEnabledProperty =
DependencyProperty.Register(nameof(TextBoxEnabled), typeof(bool), typeof(CheckBoxInput), new PropertyMetadata(OnAnyPropertyChanged));
public static readonly DependencyProperty TextBoxTextProperty =
DependencyProperty.Register(nameof(TextBoxText), typeof(string), typeof(TextCheckBox), new PropertyMetadata(OnAnyPropertyChanged));
public static readonly DependencyProperty CheckBoxCheckedProperty =
DependencyProperty.Register(nameof(CheckBoxChecked), typeof(bool), typeof(CheckBoxInput), new PropertyMetadata(OnAnyPropertyChanged));
public TextCheckBox()
=> InitializeComponent();
static void OnAnyPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
=> (obj as TextCheckBox).OnAnyPropertyChanged(args);
void OnAnyPropertyChanged(DependencyPropertyChangedEventArgs args)
=> TextPropertyChanged?.Invoke(this, args);
}
}
But nothing changed. Clicking the checkbox does not disable the TextBox. Also, breakpoints are not hit in the setter of "CheckBoxChecked".
Then I tried the answer, provided by Clemens and the XAML of my usercontrol became (only altered part posted here):
<TextBox Text="{Binding TextBoxText,
Mode=OneWayToSource,
UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
IsEnabled="{Binding TextBoxEnabled,
Mode=OneWay,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
Grid.Row="1"
Grid.Column="0"
Height="20">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=checkBox}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<CheckBox x:Name="checkBox"
Content="Newline"
IsChecked="{Binding CheckBoxChecked,
Mode=OneWayToSource,
UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1"
Grid.Column="1"
Margin="5,5,8,5"/>
But, again, nothing happens. :(
I undid all changes before trying any suggestion, so there wasn't a case where both suggestions were in effect.
uj5u.com熱心網友回復:
當未選中內容為“已啟用”的復選框時,應該啟用文本框似乎很奇怪。
你可能只是想反過來??做。為 CheckBox 命名并將 TextBox 的IsEnabled屬性系結到IsCheckedCheckBox的屬性:
<CheckBox x:Name="checkBox" .../>
<TextBox IsEnabled="{Binding IsChecked, ElementName=checkBox}" .../>
如果您確實需要反轉邏輯,請使用適當的系結轉換器,或使用 DataTrigger:
<TextBox ...>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger
Binding="{Binding IsChecked, ElementName=checkBox}"
Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/372422.html
標籤:c# wpf user-controls
上一篇:如何使網格填充視窗?
下一篇:如何遍歷TreeView元素?
