在点击按钮(MVVM模式)后,wpf更改列宽

时间:2019-02-22 16:44:41

标签: c# xaml

我尝试在单击按钮后更改列宽。

我正在学习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);
 }

5 个答案:

答案 0 :(得分:0)

正如Daniel在上述评论中提到的那样,您需要实现INotifyPropertyChanged。马克·格雷夫(Marc Gravell)关于这个问题(Implementing INotifyPropertyChanged - does a better way exist?)的答案包含了您需要做的所有信息。

此外,您需要更改绑定以包括ModeUpdateSourceTrigger(见下文):

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

答案 1 :(得分:0)

我尝试听从您的建议。我更新代码以插入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和绑定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)
        };

    }

答案 2 :(得分:0)

就像大多数人所说的那样,您需要在变量绑定到的位置具有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;
    }
}

从那里我们可以创建要绑定到的变量。也许有更好的方法来执行此操作,但是我总是将变量绑定为这种方式。

everyourvariableis.cs

private double _NotamWidth;

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

答案 3 :(得分:0)

您可以将其设置为“自动”,然后绑定该列的根面板的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>
在您将ViewModel中的

INotifyPropertyChanged保留为必不可少的同时,还需要将窗口/应用程序的DataContext设置为ViewModel的实例。

P.S .:请注意,Grid.Width属性具有不同的类型。您应该在ViewModel中更新 NotamWidh 属性的类型

答案 4 :(得分:0)

您好,谢谢您的回答。

我会尽你所能。但是我仍然可以使用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);


    }

找到解决方案后,我将保持代码更新

西里尔