我需要将TextBox
es的高度绑定到我的数据模型。每次TextBox
调整大小时,都应更新模型。 TextBox
已调整大小,因为它会将内容包装到MaxHeight
,直到达到<Window x:Class="BindingTester.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:BindingTester"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<TextBox
Canvas.Left="234"
Canvas.Top="71"
Text="TextBox"
TextWrapping="Wrap"
ScrollViewer.VerticalScrollBarVisibility="Auto"
MaxHeight="200"
AcceptsReturn="True"
Height="{Binding TextBoxHeight, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged/>
</Canvas>
时,它会显示滚动条。我举了一个例子来证明我的问题。
public partial class MainWindow : Window, INotifyPropertyChanged
{
private double textBoxHeight;
public MainWindow()
{
InitializeComponent();
DataContext = this;
//TextBoxHeight = 100.0;
}
public double TextBoxHeight
{
get { return textBoxHeight; }
set
{
if (value != textBoxHeight)
{
textBoxHeight = value;
RaisePropertyChanged("TextBoxHeight");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
TextBoxHeight
当我使用它时,从源到目标的绑定工作正常。当我在MainWindow
的构造函数中设置TextBox
属性时,TextBox
完美地调整为100,但是大小似乎是固定的。当我没有设置它时(因为高度为100,内容很大而且#34; TextBox&#34;)首先表现得像预期的那样:TextBoxHeight
&#39 ; s大小适合内容。模型中的NaN
更新为Height
。
我知道发生这种情况是因为NaN
属性在未设置时返回ActualHeight
,而是我必须要求TextBox
。但无论如何,我认识到如果我输入一些文本(例如换行符)来调整Height
TextBoxHeight
的大小,IValueConverter
属性仍然没有更新,并且设置者是没有再次调用...我也尝试使用ActualHeight
使用TextBox
更新它,但没有成功。
我知道在这个示例中,即使我通过输入换行符来调整TextBoxHeight
的大小,NaN
每次都会使用TextBox
进行更新,但是第一次调用setter时SizeChanged
已初始化。令我困惑的是,Binding似乎无法工作......我知道问题本身的解决方案:订阅DataContext
事件,获取发件人对象的joinPoint.getTarget()
并手动设置模型。但我认为应该有一个解决方案,无需在代码隐藏中订阅和访问模型,只绑定属性。有人可以帮忙吗?
答案 0 :(得分:0)
多次阅读您的问题后,我得出以下结论:您希望TextBoxHeight变量中的文本框的当前高度。如果添加更多文本,则希望TextBox高度更改,但只有当TextBox高度超过100时,滚动条才可见。
以下代码会在添加更多文本时增加TextBox的高度。如果减少文本,TextBox的高度将降低到MinHeight值。
<TextBox x:Name="Tbx1"
Width="219"
TextWrapping="Wrap"
ScrollViewer.VerticalScrollBarVisibility="Auto"
MaxHeight="100"
AcceptsReturn="True"
MinHeight="{Binding TextBoxHeight, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SizeChanged="Tbx1_SizeChanged"
/>
////////
private void Tbx1_SizeChanged(object sender, SizeChangedEventArgs e)
{
TextBoxHeight = Tbx1.ActualHeight;
}
如果我没有正确理解你的要求,请纠正我。
答案 1 :(得分:-1)
我可以建议您使用行为或其他事件来命令机制,然后您可以监听OnResizeAction事件来处理大小更改并将这些事件转换为您想要的任何逻辑。这是一个小例子。 1. Xaml代码:
<Window x:Class="SoResizeIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:soResizeIssue="clr-namespace:SoResizeIssue"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<soResizeIssue:MainViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBox HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Text="{Binding ContentFromDataContext, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<i:Interaction.Behaviors>
<soResizeIssue:ResizeHandlingBehavior OnResizeAction="{Binding OnResizeAction, UpdateSourceTrigger=PropertyChanged}"/>
</i:Interaction.Behaviors>
</TextBox>
</Grid></Window>
2。行为代码:
public class ResizeHandlingBehavior:Behavior<FrameworkElement>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SizeChanged += AssociatedObjectOnSizeChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.SizeChanged -= AssociatedObjectOnSizeChanged;
}
private void AssociatedObjectOnSizeChanged(object sender, SizeChangedEventArgs args)
{
var action = OnResizeAction;
if(action == null) return;
action(args);
}
public static readonly DependencyProperty OnResizeActionProperty = DependencyProperty.Register(
"OnResizeAction", typeof (Action<object>), typeof (ResizeHandlingBehavior), new PropertyMetadata(default(Action<object>)));
public Action<object> OnResizeAction
{
get { return (Action<object>) GetValue(OnResizeActionProperty); }
set { SetValue(OnResizeActionProperty, value); }
}
}
3。 ViewModel代码:
public class MainViewModel:BaseObservableObject
{
private string _contentFromDataContext;
private Action<object> _onResizeAction;
public MainViewModel()
{
OnResizeAction = new Action<object>(InnerOnResizeAction);
}
private void InnerOnResizeAction(object obj)
{
var args = obj as SizeChangedEventArgs;
//do you logic here
}
public string ContentFromDataContext
{
get { return _contentFromDataContext; }
set
{
_contentFromDataContext = value;
OnPropertyChanged();
}
}
public Action<object> OnResizeAction
{
get { return _onResizeAction; }
set
{
_onResizeAction = value;
OnPropertyChanged();
}
}
}
<强>更新强> 5.此解决方案将Resize的逻辑移动到ViewModel端,而TextBlock将由于Layout重新构建和实际大小更改而更改其大小。使用此解决方案,您不必对一些实际大小参数进行绑定,只需观察大小更改并将所有逻辑从窗口代码移到视图模型一侧,即窗口(xaml.cs)代码背后完全清楚。
我希望它会对你有所帮助。 谢谢和问候,