【问题标题】:I need to open an Usercontrol in the main Window from another Usercontrol我需要从另一个用户控件的主窗口中打开一个用户控件
【发布时间】:2018-03-24 08:04:52
【问题描述】:

基本上我有这个用户控件,它是一个主菜单,带有一个新游戏按钮、一个加载按钮和一个设置按钮。 当我启动它时,我需要打开它,但更重要的是,当点击新游戏按钮时,我需要将主菜单替换为另一个用户控件。 我一直在尝试查找东西几个小时,但还没有弄清楚如何去做,所以我希望有人能告诉我我做错了什么。这是我当前的代码。

我仍然是编程的初学者,并以此作为一种变大的方式,如果我看起来很慢,请见谅。

主窗口 XAML:

<Window.Resources>
    <DataTemplate DataType="{x:Type local:MainInterfaceViewModel}">
        <local:MainInterface/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:Character_CreationViewModel}">
        <local:Character_Creation/>
    </DataTemplate>
</Window.Resources>
<Window.Background>
    <ImageBrush ImageSource="pack://application:,,,/Pokemorph Island;component/images/cover1.jpg"/>
</Window.Background>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="535*"/>
        <RowDefinition Height="36*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="90*"/>
        <ColumnDefinition Width="307*"/>
    </Grid.ColumnDefinitions>
    <DockPanel Grid.ColumnSpan="2" Grid.RowSpan="2">
        <ContentControl x:Name="FullScreen" DockPanel.Dock="Right" Content="{Binding SelectedViewModel}"/>
    </DockPanel>
    <DockPanel Grid.Column="0" Grid.RowSpan="2">
        <ContentControl x:Name="User" />
    </DockPanel>
    <Button Content="&gt;&gt;&gt;" HorizontalAlignment="Left" Click="Change_Image_UP" Style="{StaticResource RoundCorner}" Margin="66,0,0,0" VerticalAlignment="Top" Width="51" Height="31" Foreground="White" FontSize="16" FontWeight="Bold" FontFamily="Rockwell Extra Bold" Grid.Row="1"/>
    <Button Content="&lt;&lt;&lt;" HorizontalAlignment="Left" Click="Change_Image_Down" Style="{StaticResource RoundCorner}" Margin="10,0,0,0" VerticalAlignment="Top" Width="51" Height="31" Foreground="White" FontSize="16" FontWeight="Bold" FontFamily="Rockwell Extra Bold" Grid.Row="1"/>
    <Button Content="Image Source" HorizontalAlignment="Left" Click="Image_Source" Style="{StaticResource RoundCorner}" Margin="431,0,0,0" VerticalAlignment="Top" Width="84" Height="31" Foreground="White" Grid.Column="1" Grid.Row="1"/>
    <Button Content="PATREON" HorizontalAlignment="Left" Click="Patreon_Link" Style="{StaticResource RoundCorner}" Margin="520,0,0,0" VerticalAlignment="Top" Width="84" Height="31" Foreground="White" Grid.Column="1" Grid.Row="1"/>
    <Button Content="Button" Margin="0,507,0,0" VerticalAlignment="Top" Width="75" Command="{Binding MainCommand}"/>
    <Button Content="Button" Margin="134,507,584,0" VerticalAlignment="Top" Width="75" Command="{Binding CharCreaCommand}" Grid.ColumnSpan="2"/>


</Grid>

主窗口代码

public partial class MainWindow : Window
{
    int cover = 1;

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new NavigationViewModel();
        //FullScreen.Content = new MainInterface();
    }

    private void Image_Source(object sender, RoutedEventArgs e)
    {
        if (cover == 1)
            System.Diagnostics.Process.Start("---------");
        if (cover == 2)
            System.Diagnostics.Process.Start("---------");
    }
    private void Change_Image_UP(object sender, RoutedEventArgs e)
    {
        cover = cover + 1;
        if (cover > 2)
            cover = 1;
        if (cover == 1)
        {
            this.Background = new ImageBrush(new BitmapImage(new Uri(@"pack://application:,,,/Pokemorph Island;component/images/cover1.jpg", UriKind.Absolute)));
        }
        else if (cover == 2)
        {
            this.Background = new ImageBrush(new BitmapImage(new Uri(@"pack://application:,,,/Pokemorph Island;component/images/cover2.png", UriKind.Absolute)));
        }
    }
    private void Change_Image_Down(object sender, RoutedEventArgs e)
    {
        cover = cover - 1;
        if (cover < 1)
            cover = 2;
        if (cover == 1)
        {
            this.Background = new ImageBrush(new BitmapImage(new Uri(@"pack://application:,,,/Pokemorph Island;component/images/cover1.jpg", UriKind.Absolute)));
        }
        else if (cover == 2)
        {
            this.Background = new ImageBrush(new BitmapImage(new Uri(@"pack://application:,,,/Pokemorph Island;component/images/cover2.png", UriKind.Absolute)));
        }
    }
    private void Patreon_Link(object sender, RoutedEventArgs e)
    {
        System.Diagnostics.Process.Start("https://www.patreon.com/user?u=3253293");
    }
}

主菜单用户控件

<Grid>
    <Button Content="New Game" HorizontalAlignment="Left" Style="{StaticResource RoundCorner}" Margin="10,10,0,0" VerticalAlignment="Top" Width="138" Height="76" Background="#338B0000" Foreground="White" FontFamily="Segoe Print" FontSize="24" FontWeight="Bold" Command="{Binding CharCreaCommand}" CommandParameter="CharCrea"/>
    <Button Content="Load Game" HorizontalAlignment="Left" Style="{StaticResource RoundCorner}" Margin="10,91,0,0" VerticalAlignment="Top" Width="138" Height="76" Background="#338B0000" Foreground="White" FontFamily="Segoe Print" FontSize="24"/>
    <Label Content="Pokémorph Island" HorizontalAlignment="Left" Margin="103,313,0,0" VerticalAlignment="Top" Height="111" Width="616" Foreground="#CCFF00C5" FontWeight="Bold" FontFamily="Rage Italic" FontSize="80"/>
    <Button Content="Settings" HorizontalAlignment="Left" Style="{StaticResource RoundCorner}" Margin="10,172,0,0" VerticalAlignment="Top" Width="138" Height="76" Background="#338B0000" Foreground="White" FontFamily="Segoe Print" FontSize="24"/>
</Grid>

我一直在尝试使用的当前 MVVM

class NavigationViewModel : INotifyPropertyChanged
{
    public ICommand MainCommand { get; set; }

    public ICommand CharCreaCommand { get; set; }

    private object selectedViewModel;

    public object SelectedViewModel
    {
        get { return selectedViewModel; }

        set { selectedViewModel = value; OnPropertyChanged("SelectedViewModel"); }
    }

    public NavigationViewModel()
    {
        MainCommand = new BaseCommand(OpenMain);

        CharCreaCommand = new BaseCommand(OpenCharCrea);
    }

    private void OpenMain(object obj)
    {
        SelectedViewModel = new MainInterfaceViewModel();
    }

    private void OpenCharCrea(object obj)
    {
        SelectedViewModel = new Character_CreationViewModel();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

public class BaseCommand : ICommand
{
    private Predicate<object> _canExecute;
    private Action<object> _method;
    public event EventHandler CanExecuteChanged;

    public BaseCommand(Action<object> method)
        : this(method, null)
    {
    }

    public BaseCommand(Action<object> method, Predicate<object> canExecute)
    {
        _method = method;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null)
        {
            return true;
        }

        return _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _method.Invoke(parameter);
    }
}

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    WPF 的学习曲线是出了名的艰难。部分是因为使用了 MVVM 模式,它需要一定的横向思考。 如果您认为“这很难”,那很正常。你没有慢。

    那里有各种代码。尝试并朝着绑定一切并远离事件的方向发展。 我还建议您使用 mvvmlightlibs 框架。在解决方案资源管理器中右键单击项目,选择管理 nuget 包并添加包。对大多数 icommand 使用 relaycommand。还有一个基本视图模型实现了 inotifypropertychange,您可以从中继承视图模型。除非你需要序列化它们。

    执行此操作的一种方法是将要切换的用户控件托管在内容控件中。将内容绑定到视图模型中的属性。然后将其设置为两个视图模型之一。我不知道该怎么称呼它们,比如说开始和游戏。因此,您将拥有一个带有初始按钮的 StartView 和一个带有游戏期间所需按钮的 GameView。然后,您将拥有一个 startVM 和 GameVM 视图模型,其中包含与您的按钮相对应的命令。

    我认为您在代码中几乎有这个想法,但示例模板可能如下所示:

    <DataTemplate DataType="{x:Type local:StartVM}">
        <local:Start/>
    </DataTemplate>
    

    那些有范围。所以你可以把它放在一个窗口的资源中,它是整个窗口或一个网格,它只是那个网格。 您还可以将它们放在资源字典中,将该资源字典合并到 app.xaml 中,它会影响您应用中的所有位置。

    然后,您需要您的 contentcontrol 将其内容绑定到一个属性,该属性将为其提供 gamevm 或 starvm。你看起来像你一样。有点像。

    <ContentControl Content="{Binding CurrentViewModel}"
    

    我试图解释所有这些东西,但我认为这会给我们带来你的问题。 您需要一个命令来设置 SelectedViewModel 属性,而您所拥有的只是一种方法。 以下是一些中继命令示例: https://msdn.microsoft.com/en-gb/magazine/dn237302.aspx

    你的布局看起来也有点奇怪。 我不会使用停靠面板,我建议只使用网格。 通常我希望工具栏类型的交易是顶部窄横幅和其下方的一些内容。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 2021-11-12
      • 2018-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-04
      • 2011-11-11
      相关资源
      最近更新 更多