当我尝试将窗口的高度和宽度绑定到视图模型中的属性时,我遇到了一些问题。这是一个小样本应用程序来说明问题。这是app.xaml.xs中的代码
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow mainWindow = new MainWindow();
MainWindowViewModel mainWindowViewModel = new MainWindowViewModel();
mainWindow.DataContext = mainWindowViewModel;
mainWindow.Show();
}
}
这是MainWindow.xaml:
<Window x:Class="TestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="{Binding WindowHeight}"
Width="{Binding WindowWidth}"
BorderThickness="{Binding WindowBorderThickness}">
</Window>
这是视图模型:
public class MainWindowViewModel
{
public int WindowWidth { get { return 100; } }
public int WindowHeight { get { return 200; } }
public int WindowBorderThickness { get { return 8; } }
}
当程序启动时,会调用WindowHeight和WindowBorderThickness(但不是WindowWidth)的getter,因此窗口的高度和边框设置正确,但不是宽度。
然后我添加了将触发所有属性的PropertyChanged的按钮,以便视图模型现在看起来像这样:
public class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void TriggerPropertyChanges()
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("WindowWidth"));
PropertyChanged(this, new PropertyChangedEventArgs("WindowHeight"));
PropertyChanged(this, new PropertyChangedEventArgs("WindowBorderThickness"));
}
}
public ICommand ButtonCommand { get { return new RelayCommand(delegate { TriggerPropertyChanges(); }); } }
public int WindowWidth { get { return 100; } }
public int WindowHeight { get { return 200; } }
public int WindowBorderThickness { get { return 8; } }
}
现在,当我单击按钮时,将调用WindowBorderThickness的getter,但不会调用WindowWidth和WindowHeight的getter。这一切看起来都非常奇怪而且与我不一致。我错过了什么?
答案 0 :(得分:38)
尝试使用双向绑定,它对我有用:
Width="{Binding Path=xExt, Mode=TwoWay}"
答案 1 :(得分:10)
我有同样的问题,我注意到它取决于是否首先在xaml中写入高度或宽度。如果高度是第一个,那么Binding只为它工作,反之亦然。解决方案是将Binding模式设置为'TwoWay': 我所做的项目是使用MS Studio 2010和.NET 4.0
答案 2 :(得分:9)
我会尽力回答我自己的问题。绑定工作正常,但我们无法确定布局系统要求例如窗口的宽度属性。
来自MSDN:
如果此元素是某个其他元素中的子元素,则将此属性设置为值实际上只是建议值。布局系统以及父元素的特定布局逻辑将在布局过程中将该值用作非绑定输入。实际上,FrameworkElement几乎总是其他东西的子元素;即使你在窗口设置高度。 (对于Window,当底层应用程序模型建立创建承载应用程序的Hwnd的基本呈现假设时,将使用该值。)
似乎有效的解决方案是将WindowWidth属性绑定到MinWidth和MaxWidth,以及Width。其中一个将被检索,至少在我上面使用的测试场景中。
答案 3 :(得分:5)
此外,您可以将SizeToContent="WidthAndHeight"
与MinHeight
和MinWidth
一起使用,因此MaxHeight
和MaxWidth
不需要额外的通话。
答案 4 :(得分:3)
好的,
我遇到了同样的问题,无法通过XAML正确地将窗口尺寸(min,max,normal)绑定到我的viewmodel。
我不知道为什么,但如果你通过代码而不是XAML来实现它们,那么你可以毫无问题地实现所有这些绑定。
这是我的C#代码:
this.SetBinding(Window.WidthProperty, new Binding("Width") { Source = MyViewModel, Mode=BindingMode.TwoWay });
this.SetBinding(Window.HeightProperty, new Binding("Height") { Source = MyViewModel, Mode=BindingMode.TwoWay });
this.SetBinding(Window.MaxWidthProperty, new Binding("MaxWidth") { Source = MyViewModel });
this.SetBinding(Window.MaxHeightProperty, new Binding("MaxHeight") { Source = MyViewModel });
this.SetBinding(Window.MinWidthProperty, new Binding("MinWidth") { Source = MyViewModel });
this.SetBinding(Window.MinHeightProperty, new Binding("MinHeight") { Source = MyViewModel });
奇怪的是,它只适用于代码,而不适用于XAML。更为奇怪的是,默认情况下,它对于mMin和Max尺寸绑定TwoWay,但对于您必须指定«Mode = BindingMode.TwoWay»的正常尺寸不绑定。
应该有一个微软必须纠正的错误......
答案 5 :(得分:1)
绑定到MinWidth和MinHeight是正确的。此外,如果您需要绑定到MaxWidth和MaxHeight,如果您的动态将放大或缩小Window的大小。
答案 6 :(得分:0)
我不确定你的具体实现,但我只是写一个可能有帮助的例子。
XAML
<Window x:Name="MainWindow"
x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
MinWidth="200"
MinHeight="100"
Width="{Binding ElementName=MainWindow, Path=WindowWidth}"
Height="{Binding ElementName=MainWindow, Path=WindowHeight}">
<Grid>
<Slider
x:Name="slWidth"
Value="{Binding ElementName=MainWindow, Path=WindowWidth, Mode=TwoWay}"
Minimum="200"
Maximum="1600"
Height="23" HorizontalAlignment="Left" Margin="56,22,0,0" VerticalAlignment="Top" Width="61" />
<Label
Content="Width"
Height="28"
HorizontalAlignment="Left"
Margin="12,22,0,0"
Name="Label1"
VerticalAlignment="Top" />
<Slider
x:Name="slHeight"
Value="{Binding ElementName=MainWindow, Path=WindowHeight, Mode=TwoWay}"
Minimum="100"
Maximum="800"
Height="23" HorizontalAlignment="Left" VerticalAlignment="Top" Width="61" Margin="56,51,0,0" />
<Label
Content="Height"
Height="28"
HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="12,46,0,0" />
</Grid>
</Window>
代码
Class MainWindow
Public Shared ReadOnly WindowWidthProperty As DependencyProperty = _
DependencyProperty.Register("WindowWidth", _
GetType(Integer), GetType(MainWindow), _
New FrameworkPropertyMetadata(Nothing))
Public Shared ReadOnly WindowHeightProperty As DependencyProperty = _
DependencyProperty.Register("WindowHeight", _
GetType(Integer), GetType(MainWindow), _
New FrameworkPropertyMetadata(Nothing))
Public Property WindowWidth As Integer
Get
Return CInt(GetValue(WindowWidthProperty))
End Get
Set(ByVal value As Integer)
SetValue(WindowWidthProperty, value)
End Set
End Property
Public Property WindowHeight As Integer
Get
Return CInt(GetValue(WindowHeightProperty))
End Get
Set(ByVal value As Integer)
SetValue(WindowHeightProperty, value)
End Set
End Property
End Class
C#代码
public readonly DependencyProperty WindowWidthProperty = DependencyProperty.Register("WindowWidth", typeof(Double), typeof(MainWindow), new FrameworkPropertyMetadata());
public readonly DependencyProperty WindowHeightProperty = DependencyProperty.Register("WindowHeight", typeof(Double), typeof(MainWindow), new FrameworkPropertyMetadata());
public double WindowWidth {
get { return Convert.ToDouble(this.GetValue(WindowWidthProperty)); }
set { this.SetValue(WindowWidthProperty, value); }
}
public double WindowHeight {
get { return Convert.ToDouble(this.GetValue(WindowHeightProperty)); }
set { this.SetValue(WindowHeightProperty, value); }
}
答案 7 :(得分:0)
Height="{DynamicResource {x:Static SystemParameters.PrimaryScreenHeightKey}}" Width="{DynamicResource {x:Static SystemParameters.PrimaryScreenWidthKey}}"
对我来说很好。
答案 8 :(得分:0)
我已使用以下代码解决了此问题。我希望它可以帮助某人。
要点: WPF中的动态绑定始终仅对属性有效,而对变量无效。
在.xaml.cs文件中声明一个全局公共属性,如下所示:
public Double DynamicHeight { get; set; }
// Set DynamicHeight property value in Window_Loaded or any other event
private void Window_Loaded(object sender, RoutedEventArgs e)
{
DynamicHeight = 200;
}
在.xaml文件中设置动态高度,如下所示:
<Grid Height="{Binding DynamicHeight, Mode=TwoWay}">
</Grid>
如果您认为此答案有用,请对其投票。谢谢!
答案 9 :(得分:-2)
只需添加 Mode = TwoWay Width="{Binding WindowWidth, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, FallbackValue=350}"