2010-04-20 134 views
17

當我嘗試將窗口的高度和寬度綁定到視圖模型中的屬性時,出現一些問題。這裏有一個小例子來說明問題。這是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的吸叫,但不WindowWidth和WindowHeight。這一切似乎很奇怪,對我來說不一致。我錯過了什麼?

+1

您在調試時在輸出窗口中有任何警告嗎? – Drake 2010-04-20 13:59:02

+0

不,沒有警告。 – 2010-04-20 14:12:42

回答

8

我會盡量回答我自己的問題。綁定正在工作,但我們不能確定佈局系統是否要求窗口的Width屬性。

MSDN

如果該元素是一些其他的元素中的子元素,然後設置該屬性的值是真的只是一個建議值。佈局系統以及父元素的特定佈局邏輯將在佈局過程中將該值用作非綁定輸入。實際上,FrameworkElement幾乎總是別的東西的子元素;即使您在窗口上設置高度。 (有關的窗口,則當底層應用模型確立了在承載應用的HWND基本渲染假設使用該值。)

,似乎工作的溶液到WINDOWWIDTH屬性綁定爲minWidth和MaxWidth ,以及寬度。至少在我上面使用的測試場景中,其中一個將被檢索。

-1

我不認爲你可以動態設置窗口大小

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); } 
} 
+1

這裏的基本區別是,當我綁定到一個單獨的視圖模型時,你綁定到MainWindow本身。這似乎有所作爲,出於某種原因。如果我對你的視圖模型實現你的滑塊,它將不起作用(除非我也像我在自己的答案中所述那樣綁定到MinHeight和MaxHeight)。無論如何感謝這個例子。 – 2010-04-20 13:17:21

1

綁定爲minWidth和了minHeight是正確的。此外,如果您需要綁定到MaxWidth和MaxHeight,如果您的動態將會放大或縮小Window的大小。

4

此外,您可以使用SizeToContent="WidthAndHeight"MinHeightMinWidth,所以沒有多餘的調用將需要爲MaxHeightMaxWidth

9

我有同樣的問題,我注意到它取決於是否先寫入xaml的高度或寬度。如果高度是第一個,那麼綁定僅適用於它,反之亦然。解決的辦法是設置結合模式爲「雙向」: 我做了該項目與2010年MS Studio和.NET 4.0

27

嘗試使用雙向綁定,它爲我工作:

Width="{Binding Path=xExt, Mode=TwoWay}" 
1

好的,

我有同樣的問題,無法正確綁定到我的viewmodel通過XAML的窗口尺寸(最小,最大,正常)。

我不知道爲什麼,但如果您通過代碼而不是通過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。更奇怪的是,它默認綁定TwoWay的mMin和Max尺寸,但不是用於您必須指定«Mode = BindingMode.TwoWay»的Normal尺寸。

應該有一個錯誤,微軟必須糾正這一點...