C#(WPF)在不新建实例的情况下怎么调用另一个类的方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#(WPF)在不新建实例的情况下怎么调用另一个类的方法相关的知识,希望对你有一定的参考价值。

BackStage是主窗体MainWindow的一个控件,但是不继承MainWindow,继承的是其他的。
怎么在BackStage.xaml.cs里调用MainWindow.xaml.cs里的方法。不能用创建新实例的方法。
Java可以用Context实现。C#怎么实现??

    <Grid>
        <Button Click="Button_Click"></Button>
    </Grid>

        //可以通过控件找到窗体实例,
        //示例:我用button找到了MainWindow
        private void Button_Click(object sender, RoutedEventArgs e)
        
            Button b = sender as Button;//相当于BackStage
            Window w = FindAnchestor<Window>(b);
            MessageBox.Show(w.Title);
        

        // 这段直接复制
        private static T FindAnchestor<T>(DependencyObject current)
            where T : DependencyObject
        
            do
            
                if (current is T)
                    return (T)current;
                current = VisualTreeHelper.GetParent(current);
            
            while (current != null);
            return null;
        

追问

/*在其它类中代码如下*/
private final Game game; //主类(相当于MainWindow),this传过去
public PuzzleView(Context context)

this.game = (Game) context;

请问c#有没有上面的用法?

追答

最简单的,声明一个全局静态变量x,在MainWindow(被引用者)的构造函数里面,x=this;赋值,然后其他你要用的时候就引用这个x,也就是其实例。
你可以看看单例模式是怎么做到静态实例的。网上搜一下。

追问

Thank you very much !!
不过,这样做总感觉有缺点吧??之前在Java中一直就是那样做的,后来碰到了Context(上下文),就不再那样用了。C#中有没有Context的用法??

追答

什么Context,就像另外一个回答的一样,你的语文还得学学!要么就写完整的java示例出来。
C#和Java都有类似的继承、接口机制,在设计模式方面代码几乎可以无障碍移植,至于你不会移植,只能说明你自己对那个Context之类的还只是知其然不知其所以然。

追问

好吧,其实我语文就不好。HAHAHA。。日后会解决的。。
Thank you !

参考技术A 两点建议:
1,楼主补习一下语文吧……
2,Context的本意是什么?上下文。
控件的Parent是什么,是存放它的容器。你现在把窗口作为容器,那么Parent难道不是你要的东西?何来重新创建一说。
参考技术B 如果方法是静态的话 就不需要创建实例了。追问

NO,NO。也不是静态的。

追答

那就不行了啊。为什么不能实例化呢?

在不丢失单元格焦点的情况下刷新 WPF DataGrid

【中文标题】在不丢失单元格焦点的情况下刷新 WPF DataGrid【英文标题】:Refresh WPF DataGrid without losing cell focus 【发布时间】:2011-07-23 12:07:21 【问题描述】:

我有一个 WPF DataGrid,其中一些数据绑定到 LINQ to SQL 实体类。一列是显示给定航班的飞行时间的时钟,该时间是使用 Flight 的部分类中的逻辑计算的。我有一个计时器,每 2 秒调用一次 datagrid.Items.Refresh 来更新时钟。

刷新工作正常,但现在我正在添加键盘快捷键。使用键盘箭头在单元格中导航可以在定时器关闭的情况下正常工作,但在启用刷新定时器的情况下,获得焦点的单元格(实际上是整个数据网格)会失去焦点。

我需要以某种方式保持焦点(首选)或在 DataGrid 获得焦点时禁用计时器。我什至似乎无法让后者工作。我试过了:

if (!dataGrid.IsFocused)
    dataGrid.Items.Refresh();

if (!dataGrid.IsKeyboardFocused)
        dataGrid.Items.Refresh();

对于计时器,但即使数据网格被聚焦,这些属性也会返回 false。

有什么想法吗?

【问题讨论】:

只存储选中行的索引,刷新后设置selectedIndex 为什么不在绑定实体的定义中异步调用 PropertyChanged 并更改计时器(或部分实体类中的某些逻辑)调用属性。然后您可以将 UpdateSource.OnPropertyChanged 用于您的 DataGridColumn 绑定,这应该(理论上)防止整个 DG 刷新并且只刷新更改的实体(从而解决您的焦点问题并在理论上带来更好的性能)。我错过了什么吗? 【参考方案1】:

最好的方法是不要使用 dataGrid.Items.Refresh() 作为更新机制。听起来底层对象已经单独更新了。如果他们实现了 INotifyPropertyChanged,您应该尝试将列的绑定模式设置为 TwoWay Binding:

<DataGridTextColumn Binding="Binding xyz, Mode=TwoWay"/>

【讨论】:

【参考方案2】:

我认为您可能会获得当前焦点,并且在刷新网格后将所选单元格重新获得其焦点

int index = 11;
myDataGrid.SelectedItem = myDataGrid.Items[index];
myDataGrid.ScrollIntoView(myDataGrid.Items[index]);
DataGridRow dgrow = (DataGridRow)myDataGrid.ItemContainerGenerator.ContainerFromItem(myDataGrid.Items[index]);
dgrow.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

也可以查看this,它可能会对您有所帮助

【讨论】:

最初如何获取索引? 如果我是正确的,您要求在刷新之前获取索引,如果是这种情况,那么我要做的是声明一个变量并将其维护在 leftmousedown 或 up 事件处理程序中,并检查 @987654323 @然后以这种方式更新变量我会更新索引【参考方案3】:

您的单元格失去焦点,因为您更改了基础集合 (ItemsSource)。据我所知,没有漂亮的方法可以得到细胞。对于行:

如果您使用 MVVM,您可以记住您的 SelectedItemSelectedIndex 并在重新加载完成后通过绑定将其恢复。首先,这将使您处于正确的位置。两者都有不同的缺点:

SelectedItem 需要更多的工作。如果使用它,请确保在基础对象中覆盖 EqualsGetHashCode。如果您的项目在集合中是第 5 位,并且在重新加载期间出现在它之前的另一行,您仍然会在正确的行中结束 SelectedIndex 是最快的解决方案,但只是一个数字位置。如果您选择条目号 5 并且重新加载在它之前的行中合并,您最终会选择错误的行。

正如我所说,我没有尝试过使用单元格,但您可以先阅读this。也许您可以将其应用于您的问题。

【讨论】:

以上是关于C#(WPF)在不新建实例的情况下怎么调用另一个类的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在不按 Enter C# WPF 的情况下检测我的键盘

我们可以在不使用 SAS 令牌的情况下通过 c# 代码调用 Azure API 管理吗

在不丢失单元格焦点的情况下刷新 WPF DataGrid

如何在不选择新实例的情况下将一个查询的结果加入另一个查询的结果? [复制]

如何在C#中,在一个类里调用另外一个类的方法

C#在不创建实例的情况下获取属性值?