簡體   English   中英

wpf單擊按鈕后更改列寬(MVVM模式)

[英]wpf change column width after a click on a button (MVVM pattern)

我嘗試在單擊按鈕后更改列寬。

我正在學習MVVM模式,我想避免后面的代碼。

我可以將寬度初始化為0,但是在運行時無法成功更改寬度。

我給你看我的代碼副本。

希望你能幫我 !

非常感謝

歡呼西里爾

MainView.xaml

<Grid.ColumnDefinitions>
     <ColumnDefinition Width="10"/>
     <ColumnDefinition Width="{Binding NotamWidth}"/>
     <ColumnDefinition Width="*"/>
     <ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>

MainViewModel用於綁定寬度並將列寬度初始化為0

//Propoerty for column width
public GridLength NotamWidth { get; set; }
public AirportViewModel()
{
   //initialize width of column at 0
   MainGridModel MainGridModel = new MainGridModel(new GridLength(0));
   this.NotamWidth = MainGridModel.NotamWidth;
 }

MainGridModel支持網格的屬性

private GridLength notamWidth;

    public MainGridModel(GridLength width)
    {
        NotamWidth = width;
    }

    public GridLength NotamWidth
    {
        get
        {
            return notamWidth;
        }
        set {

            notamWidth = value;
        }
    }

RelayCommand用於更改列寬

public void ShowNotamExecute(object parameter)
{
 //Masque la colonne notam            
 this.NotamWidth = new GridLength(400);
 }

正如Daniel在以上評論中提到的那樣,您需要實現INotifyPropertyChanged Marc Gravell對這個問題的答案( 實現INotifyPropertyChanged-是否存在更好的方法? )包含了您需要這樣做的所有信息。

另外,您需要更改綁定以包括ModeUpdateSourceTrigger (請參見下文):

<Grid.ColumnDefinitions>
     <ColumnDefinition Width="10"/>
     <ColumnDefinition Width="{Binding NotamWidth, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
     <ColumnDefinition Width="*"/>
     <ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>

我嘗試聽從您的建議。 我更新代碼以插入InotifyPropertyChanged並更改綁定屬性。 我無法再初始化列寬,並且button命令仍未更改columndefinition寬度。 這讓我發瘋...

具有資源和更新的Binding屬性的MainView.xaml

xmlns:mw="clr-namespace:WpfAppEssaisMVVM.Model.Windows"

<Window.Resources>
    <!--Instance of mainGridModel -->
    <mw:MainGridModel x:Key="MainGridModel"/>
</Window.Resources>

<Grid.ColumnDefinitions>
        <ColumnDefinition Width="10"/>
        <ColumnDefinition Width="500" />
        <ColumnDefinition Width="{Binding Source={StaticResource MainGridModel},Path=NotamWidth, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="10"/>
    </Grid.ColumnDefinitions> 

MainGridModel實現InotifyPropertyChanged和Binding ColumnDefinition

    private GridLength notamWidth;

    public GridLength NotamWidth
    {
        get
        {
            return notamWidth;
        }
        set
        {
            notamWidth = value;
            OnPropertyChanged("NotamWidth");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string PropertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
    }

MainViewModel操縱NotamWidth屬性和relayCommand的按鈕命令

public MainViewModel()
    {
        //Initialize the column to gridlength 0
        MainGridModel MainGridModel = new MainGridModel
        {
            NotamWidth = new GridLength(0)
        };
     }
//Action on button command
public void ShowNotamExecute(object parameter)
    {
       //set the column Width
        MainGridModel MainGridModel = new MainGridModel
        {
            NotamWidth = new GridLength(400)
        };

    }

就像大多數人所說的那樣,您需要在變量綁定到的位置具有INotifyPropertChanged。

XAML:

<Grid.ColumnDefinitions>
 <ColumnDefinition Width="10"/>
 <ColumnDefinition Width="{Binding NotamWidth, UpdateSourceTrigger=PropertyChanged}"/>
 <ColumnDefinition Width="*"/>
 <ColumnDefinition Width="10"/>

然后,您需要在xaml.cs的構造函數中定義正確的“ Datacontext”。 例如,如果“ NotamWidth”是xaml.cs中的變量,則可以將Datacontext設置為等於“ this”。

xaml.cs:

Datacontext = this; 

但是,說NotamWidth是另一個類“ GridChanger”中的變量。 獲取正確的Datacontext的一種方法是,在xaml.cs中創建類“ GridChanger”的全局實例,然后使Datacontext等於該實例。

xaml.cs:

public class MainWindow 
{
    GridChanger gChng = new GridChanger();

    public MainWindow()
    {
        DataContext = gChng;
    }
}

從那里我們可以創建綁定到的變量。 也許有更好的方法來執行此操作,但是我總是將變量綁定為這種方式。

whereveryourvariableis.cs

private double _NotamWidth;

public double NotamWidth
{
    get
    {
        return _NotamWidth;
    }
    set
    {
        _NotamWidth = value;
        if (PropertyChanged != null)
        {
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(nameof(NotamWidth)));
        }
    }
}

您可以將其設置為“自動”,然后綁定該列的根面板的Width屬性,而不是綁定Grid.Column的Width。 之后,您可以在根面板中構建UI。

這是我建議的結構:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="10"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="10"/>
    </Grid.ColumnDefinitions>
    ...
    <Grid Grid.Column="1" x:Name="myRootPanelForColumn1" Width="{Binding NotamWidth}">

    </Grid>
    ...
</Grid>

除了將窗口/應用程序的DataContext設置為ViewModel的實例之外,ViewModel中的INotifyPropertyChanged仍然是必須的。

PS:請注意,Grid.Width屬性具有不同的類型。 您應該在ViewModel中更新NotamWidh屬性的類型。

您好,謝謝您的回答。

我會盡你所能。 但是我仍然可以使用MVVM模式更改列寬。 我最終決定在代碼后面加上代碼。 稍后我將再試一次以避免此解決方案

網格定義

<Grid.ColumnDefinitions>
  <ColumnDefinition Width="10"/>
  <ColumnDefinition Width="600" />
  <ColumnDefinition Width="0"/> <-- Column hide at initiliasition--!>
  <ColumnDefinition Width="*"/>
  <ColumnDefinition Width="10"/>
< /Grid.ColumnDefinitions>

點擊事件的按鈕

<Button Name="AirportButton
  Click="AirportButton_Click"
  Height="30"
</Button>

單擊事件以顯示該列。

   private void AirportButton_Click(object sender, RoutedEventArgs e)
    {
        //Set the column width at 500 after a click on the button);
        MainWindow.ff.ColumnDefinitions[2].Width = new GridLength(500);


    }

找到解決方案后,我將保持代碼更新

西里爾

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM